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.
