Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 5972019
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 22, 20262026-05-22T20:35:56+00:00 2026-05-22T20:35:56+00:00

I have got two strings in Python, A m * B s / (A

  • 0

I have got two strings in Python,

A m * B s / (A m + C m)

and

C m * B s / (C m + A m)

that are both equivalent functions of the unordered set (A, C) and the unordered set (B). m and s indicate units that can be swapped among the same but not with another unit.

So far, I’m doing permutations of A, B, and C and testing them using eval and SymPy’s == operator. This has multiple drawbacks:

  • for more complicated expressions, I have to generate a large number of permutations (in my case 8 nested for loops)
  • I need to define A, B, C as symbols, which is not optimal when I don’t know which parameters I will have (so I have to generate all of them -> terribly inefficient and messing up my variable namespace)

Is there a pythonian way to test for this kind of equivalence? It should work an arbitrary expressions.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-22T20:35:57+00:00Added an answer on May 22, 2026 at 8:35 pm

    Here is a simplified approach based on my previous answer.

    The idea is that if two expressions are equivalent under permutations, the permutation carrying one to the other must map the ith symbol in the first string (ordered by index of first occurrence) to the ith symbol in the second string (again ordered by index of first occurrence). This principle can be used to construct a permutation, apply it to the first string and then check for equality with the second string – if they are equal they are equivalent, otherwise they are not.

    Here is one possible implementation:

    import re
    
    # Unique-ify list, preserving order
    def uniquify(l):
        return reduce(lambda s, e: s + ([] if e in s else [e]), l, [])
    
    # Replace all keys in replacements with corresponding values in str
    def replace_all(str, replacements):
        for old, new in replacements.iteritems():
            str = str.replace(old, new)
        return str
    
    class Expression:
        units = ["m", "s"]
    
        def __init__(self, exp):
            self.exp = exp
    
        # Returns a list of symbols in the expression that are preceded
        # by the given unit, ordered by first appearance. Assumes the
        # symbol and unit are separated by a space. For example:
        # Expression("A m * B s / (A m + C m)").symbols_for_unit("m")
        # returns ['A', 'C']
        def symbols_for_unit(self, unit):
            sym_re = re.compile("(.) %s" % unit)
            symbols = sym_re.findall(self.exp)
            return uniquify(symbols)
    
        # Returns a string with all symbols that have units other than
        # unit "muted", that is replaced with the empty string. Example:
        # Expression("A m * B s / (A m + C m)").mute_symbols_for_other_units("m")
        # returns "A m *  s / (A m + C m)"
        def mute_symbols_for_other_units(self, unit):
            other_units = "".join(set(self.units) - set(unit))
            return re.sub("(.) ([%s])" % "".join(other_units), " \g<2>", self.exp)
    
        # Returns a string with all symbols that have the given unit
        # replaced with tokens of the form $0, $1, ..., by order of their
        # first appearance in the string, and all other symbols muted. 
        # For example:
        # Expression("A m * B s / (A m + C m)").canonical_form("m")
        # returns "$0 m *  s / ($0 m + $1 m)"
        def canonical_form(self, unit):
            symbols = self.symbols_for_unit(unit)
            muted_self = self.mute_symbols_for_other_units(unit)
            for i, sym in enumerate(symbols):
                muted_self = muted_self.replace("%s %s" % (sym, unit), "$%s %s" % (i, unit))
            return muted_self
    
        # Define a permutation, represented as a dictionary, according to
        # the following rule: replace $i with the ith distinct symbol
        # occurring in the expression with the given unit. For example:
        # Expression("C m * B s / (C m + A m)").permutation("m")
        # returns {'$0':'C', '$1':'A'}
        def permutation(self, unit):
            enum = enumerate(self.symbols_for_unit(unit))
            return dict(("$%s" % i, sym) for i, sym in enum)
    
        # Return a string produced from the expression by first converting it
        # into canonical form, and then performing the replacements defined
        # by the given permutation. For example:
        # Expression("A m * B s / (A m + C m)").permute("m", {"$0":"C", "$1":"A"})
        # returns "C m *  s / (C m + A m)"
        def permute(self, unit, permutation):
            new_exp = self.canonical_form(unit)
            return replace_all(new_exp, permutation) 
    
        # Test for equality under permutation and muting of all other symbols 
        # than the unit provided. 
        def eq_under_permutation(self, unit, other_exp):
            muted_self = self.mute_symbols_for_other_units(unit)        
            other_permuted_str = other_exp.permute(unit, self.permutation(unit))
            return muted_self == other_permuted_str    
    
        # Test for equality under permutation. This is done for each of
        # the possible units using eq_under_permutation
        def __eq__(self, other):
            return all([self.eq_under_permutation(unit, other) for unit in self.units])
    
    e1 = Expression("A m * B s / (A m + C m)")
    e2 = Expression("C m * B s / (C m + A m)")
    e3 = Expression("A s * B s / (A m + C m)")
    
    f1 = Expression("A s * (B s + D s) / (A m + C m)")
    f2 = Expression("A s * (D s + B s) / (C m + A m)")
    f3 = Expression("D s")
    
    print "e1 == e2: ", e1 == e2 # True
    print "e1 == e3: ", e1 == e3 # False
    print "e2 == e3: ", e2 == e3 # False
    
    print "f1 == f2: ", f1 == f2 # True
    print "f1 == f3: ", f1 == f3 # False
    

    As you pointed out, this checks for string equivalence under permutations without any regard to mathematical equivalence, but it is half the battle. If you had a canonical form for mathematical expressions, you could use this approach on two expressions in canonical form. Perhaps one of sympy’s Simplify could do the trick.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have two strings: the first's value is catdog and the second's is got.
I've got two PostgreSQL databases that have been created using the same sql file.
I've got two Silverlight Controls in my project, both have properties TeamId. I would
I have two websites that post news information. I just got a request to
I have got two classes, one a subclass of the other (say Animal and
I've got two hard disks in my computer, and have installed Solaris 10u8 on
I have got as follows: use constant ABC => ('one', 'two', 'three'); and I
I've got a form where I have two radio buttons and two interchangeable controls
If I have two domain names: altcognito.com and say I've got the other following
I've got the following problem: I have two tables: (simplified) +--------+ +-----------+ | User

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.