@Aaron, I'd be particularly interested in your thoughts of what should stay
and what should be replaced by a more structured OO approach.

I separate the different sections by

rr/rl.py         - some fundamental rules
rr/strat_pure.py - strategies that have nothing to do with SymPy
rr/traverse.py   - strategies that traverse a SymPy AST
rr/strat.py      - some conglomerate strategies that do depend on SymPy

matrices/expressions/mat(add/mul).py - Some rules written in normal python
language and the use of strategies to combine those rules. Can we replace
these by something higher level written in the SymPy language? If so what?
These files provide examples of the sorts of rules we'll want to write. The
rules are at the bottom
matrices/expressions/blockmatrix.py -- I replaced block_collapse (a giant
function) with rules. This is a good change but could have been done just
as easily by adding methods to existing classes. This is a more aggressive
example of using rules to program SymPy. It's rules-for-transformation
rather than just rules-for-canonicalization.

In general I'd like all of this code to be merged, even if we decide that
we'd rather build a different system going forward. This improves the
MatrixExpr module a fair amount and I may not have time to build a larger
system in the near future. Refactoring the rules should be easy if we
develop a better system in the future. A benefit to rules is that the logic
isn't buried deep in larger pieces of code.

On Sun, Oct 7, 2012 at 7:52 PM, Matthew Rocklin <[email protected]> wrote:

> The PR is ready for review. It still needs some polishing (increased
> documentation and a failing test) but it's a good working draft.
> https://github.com/sympy/sympy/pull/1560
>
>
> On Sun, Oct 7, 2012 at 11:43 AM, Sergiu Ivanov 
> <[email protected]>wrote:
>
>> On Sun, Oct 7, 2012 at 12:58 AM, Matthew Rocklin <[email protected]>
>> wrote:
>> >> The idea X Inverse(X) => Identity(X.rows) is substantially simpler than
>> >> the
>> >>
>> >> > code that was necessary to encode this rule though. This is going to
>> be
>> >> > a
>> >> > common sort of rule so this is the sort of thing we should generalize
>> >> > somehow.
>> >>
>> >> How about a predicate cancellable()?  Thus, x (op) y will be
>> >> transformed into identity if cancellable(x, y).  The generalised
>> >> function may then work as follows:
>> >>
>> >> def mat_cancellable(X, Y):
>> >>     return Y == Inverse(X)
>> >>
>> >> cancel(composite_expression, mat_cancellable, I)
>> >>
>> >> where composite_expression is an instance of Mul, Add, MatMul, MatAdd,
>> >> etc.  If it is possible to extract the identity from this operations,
>> >> then the third argument will be unnecessary.
>> >
>> > I wonder if there is a way to generalize this thinking so that it can be
>> > applied to more cases that aren't just cancellation.
>>
>> I'm not sure as to what exactly you refer to.  I actually think that
>> in all cases where a pair x (op) y is transformed into identity one
>> has a monoid (M, (op)) with identity e, so that x (op) y = e.  That
>> is, I actually think that all the cases where such reasoning is
>> applicable are cancellations in a monoid.
>>
>> >> > Ah, sorry, I was using pure in the sense of "lets just use this
>> >> > function,
>> >> > not a class that represents this function". I wasn't using "pure" in
>> the
>> >> > side-effect-free sense. I do however think that this system should be
>> >> > (mostly) side-effect free (mostly for caching, profiling, debug,
>> >> > etc....)
>> >> > That's somewhat standard in SymPy though.
>> >>
>> >> Yes, and that's an advantage.  Although functions with side-effects
>> >> should also be handled nicely, because, from what I know, there
>> >> actually are some mutable objects in SymPy.
>> >
>> > Rules as they're currently written only work on objects that inherit
>> from
>> > Basic. All Basics are immutable. Rules assume immutability. The mutable
>> > types in SymPy (notably Matrix) do not inherit from Basic.
>>
>> Ah, I see; I thought Matrix inherited from Basic as well.
>>
>> >> >> Further, when you say "pattern matching triples", do you mean
>> >> >> representing rules as triples and having the application function
>> >> >> which checks whether its argument matches from-expr and satisfies
>> the
>> >> >> condition, and then returns to-expr?
>> >> >
>> >> > Yes. I would like to write xxinv as
>> >> > X = Wild()
>> >> > xxinv = rule(X*Inverse(X), Identity(X.rows), True)
>> >> > or
>> >> > sym_transpose = rule(Transpose(X), X, X.is_symmetric)
>> >>
>> >> Looks very nice.  Shouldn't be that hard to implement either, I think.
>> >
>> > This depends on pattern matching, a challenging problem. SymPy might
>> have
>> > tools to handle it though.
>>
>> I'm not sure how well Wild works, but, apparently, we can use it to do
>> some pattern matching.  I've never used Wild, though; I just assumed
>> that it's sufficiently powerful.  If this is indeed the case, then the
>> format of rules you suggest should be straightforward to implement.
>>
>> Sergiu
>>
>> --
>> 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.

Reply via email to