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.

Reply via email to