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.

Reply via email to