How interdependent are __eq__ and __hash__ in sympy? On 13 March 2012 21:27, Aaron Meurer <[email protected]> wrote: > On Tue, Mar 13, 2012 at 11:01 AM, Alexey U. Gudchenko <[email protected]> wrote: >> 09.03.2012 03:05, [email protected] пишет: >>> It seems that this is not sustainable because 1. Adding too much >>> stuff to Mul and Add >>> https://code.google.com/p/sympy/issues/detail?id=1941 >> >> >> >> >> Current situation with the flatten, how I imagine it. >> Correct me If I am mistaken. >> >> 1. `flatten` is the method for associative operations `AssocOp`. >> >> (a op b) op c == a op (b op c) == a op b op c. >> >> `Add` and `Mul` are inherited from AssocOp, which in its turns is >> inherited from Expr. >> >> See picture >> https://github.com/sympy/sympy/wiki/UD-Core-Docs >> >> >> 2. The original aim for this method was the flatting of the associative >> operation trees (the 'name-token' about it.): >> >> Add( x, Add(y, z)) --> Add(x, y, z) >> >> >> This logic is implemented in AssocOp.flatten >> >> 3. Then the commutative and non-commutative symbols was introduced, so >> the `flatten` return a few lists: commutative, non commutative. >> >> (Additionally the `order_symbols` is resulted.) >> >> 4. Then the problem was raised how to check an equality of two `Expr` >> quickly. >> >> x + y = y + z >> >> This problem was solved with the help of the hashes. Hash of the `Add` is >> basically hash of the tuple of argument's hashes. >> >> >> hash(Add(x, y)) == hash(Add.args). >> >> 5. The problem of the equality 'x + y' and 'y + x' (commutative case), >> was solved with the aim of so-called `canonical ordering` of arguments. >> >> Note, that this sorting is something random and unexpected, because it >> is simply based on the sorting of python's hashes (and therefore it >> depends on the machine and bits) >> >> Also, there is this comment in code of Add.flatten >> >> # order args canonically >> # Currently we sort things using hashes, as it is quite fast. A >> better >> # solution is not to sort things at all - but this needs some more >> # fixing. NOTE: this is used in primitive, too, so if it changes >> # here it should be changed there. >> >> In PR 722 I successfully remove this sorting. >> >> >> 6. Note, that ordering of the arguments is implemented and for printing >> system also, independently. >> (display the objects in a standard sort) >> >> Also sorting of terms is used in classes such as polynomials by them own >> internally. >> >> So, the `Canonicalization` is used in a few places and have variouse >> aims, (And the aim `help with campare objects` of canonicalization >> encapsulated in flatten, not in the hash calculation, is falsly I think) >> >> 7. Also, in the constructors of `Add` and `Mul` (in `flatten` now), >> there is the so called `simplification-on-the-fly` algorithms. >> >> In particular: >> a) Add.flatten: collect similar terms in (x + 2y + 3x --> 4x + 2y) >> b) Mul.flatten: convert 1/(x*y) --> x**(-1)*y**(-1) >> >> Conclusion: >> >> We should document and *split* tasks, aims and implementation for: >> >> - flatten >> - hashing for comparison >> - canonical sorting (for printing, or polytools) >> - simplification-on-the-fly >> - commutative, non-commutative cases problems. >> >> If we can split the flatten, then (I think) there are no problems with >> >> **It seems that this is not sustainable because 1. Adding too much stuff >> to Mul and Add >> https://code.google.com/p/sympy/issues/detail?id=1941** >> >> Just polymorph those methods for other objects. >> >>> Commutativity also means that the order of the final expression can >> (and should) >>> be canonicalized, so that it's easy to assert that x*y == y*x >> >> I think no, we shouldn't. >> The comparison algorithm must be separated from `flatten` method. > > I think maybe a problem is that some code assumes that a == b implies > that a.args == b.args. We'd have to try it and run the tests to see > how ingrained this is (but I seem to remember removing the ordering > from Add, and a *ton* of tests failed, but that may have just been > because I failed to correctly redefine __eq__). > > But it would be interesting if we could do something like x*y and y*x > and keep the order, but still have them compare equal. Then, we could > make the printer give things in exactly the order they were entered, > for example. > > Aaron Meurer > > >> >> It can be implemented with the help of hash calculation function, >> so it is sufficient to encapsulate the sorting function to the >> `_hashable_content`. >> >> >> >> >> -- >> Alexey U. >> >> -- >> You received this message because you are subscribed to the Google Groups >> "sympy" group. >> To post to this group, send email to [email protected]. >> To unsubscribe from this group, send email to >> [email protected]. >> For more options, visit this group at >> http://groups.google.com/group/sympy?hl=en. >> > > -- > You received this message because you are subscribed to the Google Groups > "sympy" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/sympy?hl=en. >
-- You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/sympy?hl=en.
