Rewrite rules don't respect the canonicalization that happens at expression
construction time. If this is important to you then inject the `rebuild`
rule which effectively does type(x)(*map(rebuild, x.args))

Here is my solution to your problem

In [1]: from sympy.rules import chain, rebuild, debug, typed
In [2]: from sympy.rules.traverse import bottom_up
In [3]: e = y*(x + 3) - y
In [4]: fn = bottom_up(chain(rebuild, typed({Add: lambda x:S.One}))) #
without debug
In [4]: fn = bottom_up(chain(*map(debug, (rebuild, typed({Add: lambda
x:S.One})))))
In [5]: fn(e)
Rule: switch_rl
In:   x + 3
Out:  1

Rule: rebuild
In:   y
Out:  y

Rule: rebuild
In:   -y + y
Out:  0

This function first rebuilds/canonicalizes the expr, then turns the node
into S.One if the type is Add.  It applies this function throught the tree,
starting at the leaves and working upwards.  I've injected a debug strategy
so that you see whenever one of the bottom level rules activates.

The first rebuild seems to be y*1 -> y.  SymPy printing doesn't respect 1s
in Muls

In [36]: str(Mul(y, 1, evaluate=False))
Out[36]: y



On Tue, Feb 5, 2013 at 6:44 PM, smichr <[email protected]> wrote:

> I did the following bottom_up traversal and got an unexpected result:
>
> >>> e
> y*(x + 3) - y
> >>> bottom_up(condition(lambda x:x.is_Add, lambda x:S.One))(e)
> 1
>
> I confirmed with the debugger that Add(-y, y) is created but apparently in
> an unevaluated manner. If it were evaluated, that should have collapsed to
> 0 and then there would be no Add to be identified as 1. If I try to slip a
> recalculation of the x I get an error:
>
> >>> cond = lambda x:Add(*Add.make_args(x)).is_Add
> >>> bottom_up(condition(cond, lambda x:S.One))(e)
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "sympy\rules\traverse.py", line 19, in bottom_up_rl
>     return rule(new(type(expr), *map(bottom_up_rl, expr.args)))
>   File "sympy\rules\strat_pure.py", line 27, in conditioned_rl
>     if cond(expr):
>   File "<stdin>", line 1, in <lambda>
>   File "sympy\core\cache.py", line 92, in wrapper
>     func_cache_it_cache[k] = r = func(*args, **kw_args)
>   File "sympy\core\operations.py", line 38, in __new__
>     c_part, nc_part, order_symbols = cls.flatten(args)
>   File "sympy\core\add.py", line 179, in flatten
>     noncommutative = noncommutative or not s.is_commutative
> AttributeError: is_commutative
>
> /c
>
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/sympy?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sympy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to