Thanks for the detailed e-mail. It's great to get additional opinions from people who have used rules. You've brought up some good issues. I'll write my responses inline.
On Fri, Nov 2, 2012 at 8:59 AM, Stefan Krastanov <[email protected] > wrote: > There is one important performance enhancement that is not implemented > in rewrite rules, namely autoevaluation. However here I am considering > the "canonicalization" work done by the autoevaluation and I will > imagine that performance is not an issue. > > I think that while the state of the code that implements it in sympy > is bad, the notion itself is sufficiently well abstracted: in the > core, autoevaluation is all that is done by the constructor of an > object. This will be my definition of autoevaluation for the rest of > the post. > > My question is, is it a good idea to add a very basic rule like > call_constructor that traverses the raw tree created by Basic.__new__ > and that calls type(node)(args) in order to force the autoevaluation? > I really like this idea. The Basic.__new__ approach plays havoc with Exprs, which depend on their construction code. My solution to this so far has been "don't use Exprs and rules", but this admittedly isn't a very good solution. I think that a traversed rebuild rule called at the end of most computations might resolve many of these issues. > My knee-jerk reaction is that this is a bad idea and that > canonicalization done by the rules should have nothing to do with > autoevaluation, unlike what the core does. Basically rules should not > support the notion of autoevaluation. Let's leave the performance > issues for later. > I agree with the idea that we should not mix these two paradigms. I support experimentation with a rebuild rule, we shouldn't hard-code it in though. > However this brings another issue, which made me write this. If you > agree with me on the previous points, how will you implement the > following: > > my_simplification_function() - a function that looks in the tree and > if it finds a Trace(very_special_matrix_a**2*stuff) returns > scalar*Trace(stuff). > > points to consider: > > 1. I want to use only the following custom rule: > very_special_matrix_a**2 -> scalar*Identity > > 2. Trace will not be autoevaluated, so my rule will not factor out the > scalar out of the trace and will not remove the identity. How do I > implement a rule that does this. Doing it in my rules is not > appropriate as this should have already been implemented for the Trace > and MatMul classes. The question is, how to get a general rule that > does those already implemented canonicalization. It is basically what > autoevaluation does. How do I get the object specific canonicalization > rules? > The answer here is that Trace shouldn't depend on auto-evaluation (this is what I was warning about when I said that the MatrixExpr transformation to rules is only half done.) Trace should have a rule Trace(scalar * Matrix) -> scalar*Trace(Matrix) And you should make your simplification_function with this rule as well. You should also include any other standard canonicalization rule that you might need. We don't yet have a way to query these but we should. > 3. How do I add the my_simplification_function to the simplify > function. _eval_simplify() does not work for this, because the objects > that need to be simplified are inside a very generic container. What > about creating a full_simplify function that first lists all nodes, > ask the nodes whether they want to supply new simplification functions > and then call > simplify(chain(*newly_supplied_rules)(expr)) > I think this gets to how we globally organize rules. Object oriented approach: We could have each Class own a collection of rules. We could ask each node in the tree to supply a set of rules and then use that with a basic canonicalization strategy. I think this is what you're suggesting. Global database approach: We could have a global registry, give each rule tags, and query based on tags. This allows us to find rules that might not cleanly associate to any single class. Other approach: ... There are lots of options here. I think conversation in this area is fruitful. > Most burning for me is issue number 2. > For now I would rule-ize Trace and make my_simplification_function = canon(trace_unpack_scalar, your_special_rule) -- 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.
