I think we are going to constantly have this battle between things being unevaluated and evaluating them (at construction time) as long as we try to do both with the same class. It's a similar issue as http://code.google.com/p/sympy/issues/detail?id=1887. If you are conflicted between wanting something to do two things, instead of arguing about which it should do, maybe the best solution is to just make two classes. In this case, it means that we need a user-level class Trace that does the autosimplification at construction time, and another class that represents an unevaluated trace that you can use to build your unification rules, or as intermediaries of matrix transformation rules, or whatever.
This is the same thing as I was saying in the rules PR about need two classes (https://github.com/sympy/sympy/pull/1560#issuecomment-9640562, and also the next two comments). Of course, you could also try to represent things just using Symbols. This is like my original suggestion of an identity rule that represents sin(x)**2 + cos(x)**2 = 1 as the equation with Symbols s**2 + c**2 = 1 and the mapping {s:sin, c:cos}. Creating unevaluated classes may be cleaner in the long run, but trying to do it with the classes without creating unevaluated versions will just be a constant battle and will never work. Aaron Meurer On Fri, Nov 2, 2012 at 9:51 AM, Stefan Krastanov <[email protected] > wrote: > Given the comments of both of you I propose the following addition > (isolated to the rules module in order not to cause too much arguing): > > - adding a gather_rules function that traverses the tree and checks > for any rules registered with the objects. For instance > my_very_special_matrix object will have the following property > > my_very_special_matrix.rules_register = {'simplify': > [the_rule_square_is_identity,]} > > and trace will have > > Trace.rules_register = {'canonicalize': [trace_unpack_scalar, ]} > > This will be slow, but it will permit great freedom. We can optimize it > later. > > It will also work with the ugly idea that I had about calling all the > constructors. > > ClassUnsupportedByRules.rule_register = {'canonicalize': > [call_the_constructor, ]} > > On 2 November 2012 16:42, Stefan Krastanov <[email protected]> > wrote: > >> How do you get Matrix => scalar? > > very_special_matrix**2 is equal to scalar*Identity. The scalar is > > (should be) factored out of the Trace. > > > >>> points to consider: > >>> > >>> 1. I want to use only the following custom rule: > >>> very_special_matrix_a**2 -> scalar*Identity > > > > > > > > > >> Why is Trace not auto evaluated? I suppose you're creating it via > >> Basic__new__ rather than the Trace constructor? This is getting to the > >> issue that Ronan foresaw in the original pull request. Basic.__new__ > >> seemed ok to me, but only to create the original object. Using it to > >> create new objects instead of their constructors is a bad idea. > > > > The way that trace works is not based on canonicalization in the > > constructor (or at least when it is fixed it wont be) hence my > > disagreement with your comment and Ronan. > > -- > 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.
