6

I am looking for C++ open-source library (or just open-source Unix tool) to do: Equality test on Equations .

Equations can be build during runtime as AST Trees, string or other format.

Equations will mostly be simple algebra ones, with some assumptions about unknown functions. Domain, will be integer arithmetic (no floating point issues, as related issues are well known - Thanks @hardmath for stressing it out, I've assumed it's known).

Example: Input might contain function phi, with assumptions about it (most cases) phi(x,y)=phi(y,x) and try to solve :

equality_test( phi( (a+1)*(a+1) , a+b ) = phi( b+a, a*a + 2a + 1 )

It can be fuzzy or any equality test - what I mean is that, it does not have to always succeed (It may return "false" even if equations are equal).

If there would be problem with supporting assumptions like above about phi function, I can handle this, so just simple linear algebra equations equality testers are welcome as well.

  • Could you recommend some C/C++ programming libraries or Unix tools ? (open-source)
  • If possible, could you attach some example how such equality test, might look like in given library/tool ?

P.S. If such equality_test could (in case of success) return isomorphism - (what I mean, a kind of "mapping") - between two given equations, would be highly welcome. But tools without such capabilities are highly welcome as well.

P.S. By "fuzzy tester" I mean that in internals equation solver will be "fuzzy" in terms of looking for "isomorphism" of two functions, not in terms of testing against random inputs - I could implement this, for sure, but I try to find something with better precision.

P.P.S. There is another issue, why I need better performance solution, than brute-force "all inputs testing". Above equation is simplyfied form of my internal problem, where I do not have mapping between variables in equations. That is, I have eq1=phi( (a+1)*(a+1) , a+b ) and eq2=phi( l+k, k*k + 2k + 1 ) , and I have to find out that a==k and b==l. But this sub-problem I can handle with "brute-force" approach (even asymptotic complexity of this approach), case there is just a few variables, let it be 8. So I would need to do this equation_test for each possible mapping. If there is a tool that that whole job, I would be highly thankful, and could contribute to such project. But I don't require such functionality, simply equation_test() will be enough, I can handle rest easily.

To sum it up:

  • equality_test() is only one of many subproblems I have to solve, so computational complexity matters.
  • it does not have to be 100% reliable, but higher likelihood, than just testing equations with a few random inputs and variable mapping is highly welcome :).
  • output of "yes" or "no" (all additional information might be useful but in future, at this stage I need "Yes"/"No")
Grzegorz Wierzowiecki
  • 10,545
  • 9
  • 50
  • 88
  • 1
    In one of the comments to quant_dev's answer you mention the intended use is in a compiler. It is well known that ["mathematically equivalent expressions can produce different values using floating-point arithmetic"](http://www.lahey.com/float.htm). A classic example is using [the quadratic formula](http://en.wikipedia.org/wiki/Quadratic_equation#Floating_point_implementation) to find both roots of a second degree polynomial. – hardmath Aug 11 '11 at 13:41

4 Answers4

5

Your topic is one of automated theorem proving, for which a number of free/open source software packages have been developed. Many of these are meant for proof verification, but what you ask for is proof searching.

Dealing with the abstract topic of equations would be the theories mathematicians call varieties. These theories have nice properties with respect to the existence and regularity of their models.

It is possible you have in mind equations that deal specifically with real numbers or other system, which would add some axioms to the theory in which a proof is sought.

If in principle an algorithm exists to determine whether or not a logical statement can be proven in a theory, that theory is called decidable. For example, the theory of real closed fields is decidable, as Tarski showed in 1951. However a practical implementation of such an algorithm is lacking and perhaps impossible.

Here are a few open source packages that might be worth learning something about to guide your design and development:

Tac: A generic and adaptable interactive theorem prover

Prover9: An automated theorem prover for first-order and equational logic

E(quational) Theorem Prover

hardmath
  • 8,753
  • 2
  • 37
  • 65
  • Thank you for references, I am digging into it ;). – Grzegorz Wierzowiecki Aug 11 '11 at 19:26
  • "Automated theorem proving seems promising. Could you give my example in any of such tools? – Grzegorz Wierzowiecki Aug 12 '11 at 07:20
  • Interested readers who want to follow along may find eProver is included in their favorite Linux distribution. The Ubuntu maintainers provide it in the Universe repository. – hardmath Aug 12 '11 at 21:43
  • 1
    It might be worth looking into calling Prolog from C++ to solve this kind of problem. It seems like it'd be a natural fit to write down your algebraic transformations and knowledge about unknown functions as facts and rules and let Prolog handle the process of transforming one statement into another. – Sujay Jayakar Aug 13 '11 at 15:30
  • Now I am trying to solve problem it with [Gnu Prolog](http://www.gprolog.org/). Additionally I've found in my favourite [Arch 64 linux distro](http://www.archlinux.org/) , in [AUR](http://aur.archlinux.org/) a lot of packages under [query "prover"](http://aur.archlinux.org/packages.php?K=prover), including: alt-ergo, otter, prover9, simplyfy-bin, spass, yices, z3 and "gnu prolog", "Swi-prolog" packages in [Comunity repository](http://www.archlinux.org/packages/?q=prolog). – Grzegorz Wierzowiecki Aug 14 '11 at 10:51
3

I am not sure for any library but how about you do it yourself by generating a random set of inputs for your equation and substituting it in both equations which have to be compared. This would give you a almost correct result given you generate considerable amount of random data.

Edit: Also you can try http://www.wolframalpha.com/

with

 (x+1)*(y+1) equals x+y+xy+2

and

 (x+1)*(y+1) equals x+y+xy+1
FUD
  • 5,114
  • 7
  • 39
  • 61
  • 1
    I was thinking the same. It is a reasonable solution to start with. – André Puel Aug 11 '11 at 11:12
  • Tanks. It's fuzzy approach I think about, but try to find something with better precision. – Grzegorz Wierzowiecki Aug 11 '11 at 11:13
  • Thank you @ChingPing for stressing out that possiblity. I understand how important it is to stree out , that it is not the way I would like to do. :). – Grzegorz Wierzowiecki Aug 11 '11 at 11:17
  • yes, i am sure that is one of the trivial ways to do it. Lets wait for interesting replies. :) – FUD Aug 11 '11 at 11:20
  • Thanks @Andre-Puel for ans. I understood to stress out the fact, that equation_test is only one of many sub-problems I have to solve, so complexity matters. – Grzegorz Wierzowiecki Aug 11 '11 at 11:27
  • @ChingPing - Please cut-out wolframalpha -> on it's backend, there is mathematica which is very "heavy" and "expensive" software package. That's why I streesed out it has to be opensource. From opensource alternatives I know [Sage](http://www.sagemath.org/) which is propably backend-ed with [Maxima](http://maxima.sourceforge.net/) - so Maxima might solve it, but I don't know as much maxima langage, that's why I asked for examples. And even thou ... Maxima is rather "heavy" package as well, but as least, it's Unix and opensource. – Grzegorz Wierzowiecki Aug 11 '11 at 11:42
3

I think you can get pretty far with using Reverse Polish Notation.

  1. Write out your equation using RPN

  2. Apply transformations to bring all expressions to the same form, e.g. *A+BC --> +*AB*AC (which is the RPN equivalent of A*(B+C) --> A*B+A*C), ^*BCA --> *^BA^CA (i.e. (B*C)^A --> B^A * C^A)

  3. "Sort" the arguments of symmetric binary operator so that "lighter" operations appear on one side (e.g. A*B + C --> C + A*B)

  4. You will have problem with dummy variables, for example sum indices. There is no other way, I think, but to try every combination of matching them on both sides of the equation.

In general, the problem is very complicated.

You can try a hack, though: use an optimizing compiler (C,Fortran) and compile both sides of the equation to optimized machine code and compare the outputs. It may work, or may not.

quant_dev
  • 6,181
  • 1
  • 34
  • 57
  • What about transformations, It's one of ideas that came to my mind as well. It all boils down to comparing trees. But unfortunatelly, I am afraid, It might not work in all cases - I am not sure about reliability/unreliability of this approach. – Grzegorz Wierzowiecki Aug 11 '11 at 11:47
  • I liked your tricky approach about using compiler and it's optimisations. But in this case, what I am actually doing, I am writting compiler pass, so I have hands on all those transformations and optimization tools, and still it's not enough. But even thou, nice to stress out, as it might sound very tricky for other readers - ones again , thanks. – Grzegorz Wierzowiecki Aug 11 '11 at 11:50
  • 1
    @Grzegorz A brute force approach to transformations would be to write the expression in a RPN form as a string and apply regular expressions to it (yes, I know the Jamie Zawinski quote about regexps). – quant_dev Aug 11 '11 at 11:56
1

Opensource (GPL) project Maxima has tool simmilar to Wolfram Alpha's equals tool :

(a+b+c)+(x+y)**2 equals (x**2+b+c+a+2*x*y+y**2)

Which is is(equal()), that solves formulas :

(%i1) is(equal( (a+b+c)+(x+y)**2 , (x**2+b+c+a+2*x*y+y**2) ));
(%o1)                                true

For this purpose, it uses rational simplifier - ratsimp, in order to simplify the difference of two equations. When difference of two equations is simplified to zero, we know they are equal for all possible values:

(%i2) ratsimp( ((a+b+c)+(x+y)**2) - ((x**2+b+c+a+2*x*y+y**2)) );
(%o2)                                  0

This answer, just shows direction (like other answers). If you know about something similar, that can be used as a part of C++ Unix program - programming library ? Good C/C++ binding similar tool to this. Please, post new answer.

Grzegorz Wierzowiecki
  • 10,545
  • 9
  • 50
  • 88