On Wed, Jul 3, 2013 at 1:48 PM, Aaron Meurer <[email protected]> wrote:
> Brian, I think you dropped off list. Forwarding to sympy.
>
> Aaron Meurer
>
> On Wed, Jul 3, 2013 at 2:29 PM, Brian Granger <[email protected]> wrote:
>> I think that having multiple dispatch is something that is needed within
>> SymPy.  Multiple people have run into the difficulties with providing custom
>> Add/Mul logic for their new types.  In quantum, we just punted and used the
>> builtin Add/Mul logic, but it was a bad compromise to make.
>>
>> For this, I think looking at Mathematica is really important.  This is
>> handled by Mathematica's Rules and Patterns which are documented here:
>>
>> http://reference.wolfram.com/mathematica/guide/RulesAndPatterns.html
>> http://reference.wolfram.com/mathematica/tutorial/Introduction-Patterns.html
>>
>> If we don't have first class, nested and general pattern matching, we can't
>> do multiple dispatch.  The case in point is classes that accept *args such
>> as Add and Mul.  Good fast pattern matching would also allow us to do much
>> of the logic in Add/Mul constructors using patterns:
>>
>> Add(x_, x_) -> 2*x_
>> Mul(x_, x_)  -> x**2

Pattern matching is another way to implement CAS, but I am actually not
sure this is how Mathematica works inside. Also in pure Python, this might
be really slow (I don't know). I don't see all the little details for
pattern matching
approach. I think I can see more of the details for the sympy approach though.

>>
>> etc.
>>
>> Summary - simple type based dispatch won't do - we need full blown pattern
>> matching and transformation logic.

Why wouldn't simple type based dispatch work?
You might be right, I just want to understand the problem more.



To answer Aaron's question:

On Wed, Jul 3, 2013 at 12:58 PM, Aaron Meurer <[email protected]> wrote:
> So, going back to what we discussed the first time we met in Los
> Alamos, how would you reimplement something like the oo logic so that
> it lives entirely in the Infinity class, not in Add.flatten (say for
> simplicity, oo + 3 should go to oo, but oo + 3*I should remain as oo +
> 3*I)?

This, and another example is x + O(x). Let's stick to oo + 3.

This is a very good question and it is one of the details that I don't
know the answer 100% yet.
But I feel it is solvable.

The general idea is that you create a new type, let's say Infinity and
register mul, add, div, sub, pow using dispatch, which specify how
your new type should be handled.

In particular, it would look something like:

@dispatch(Infinity, Basic)
def mul(a, b):
    if isinstance(b, Integer):
        return a
    else:
        return Add(a, b)

This covers most usecases for "oo", since when you construct it in
Python, you always use the two argument mul(a, b). Also when Add is
constructed, the algorithm simply takes one term at a time and "adds"
it to what is in Add already. So those are all binary operations that
could be overridden in principle.

For example a faster core might decide for speed reasons to not allow
"oo" and O(x) terms. Then multiple dispatch would pretty much make
sure that either the fast core will be used if you do add(x, y), but
slow and more general sympy core will be used if you do add(x, oo).


I think the best would be to create a demo (from scratch) where we can
play with these ideas. Hopefully I'll get to this eventually.

Ondrej

>>
>> Cheers,
>>
>> Brian
>>
>>
>> On Wednesday, July 3, 2013 10:27:19 AM UTC-7, Aaron Meurer wrote:
>>>
>>> No, Add(x, y, z, t) is not just used for fast construction. Any
>>> algorithm that recurses through an expression tree and rebuilds things
>>> will rebuild an Add in that way, using expr.func(*expr.args).
>>>
>>> Aaron Meurer
>>>
>>> On Wed, Jul 3, 2013 at 12:22 PM, Ondřej Čertík <[email protected]>
>>> wrote:
>>> > On Wed, Jul 3, 2013 at 11:15 AM, Aaron Meurer <[email protected]> wrote:
>>> >> I don't think it's so easy, because Add has *args.
>>> >
>>> > If you are talking about things like:
>>> >
>>> > In [2]: Add(x, x, x, y, x, x)
>>> > Out[2]: 5⋅x + y
>>> >
>>> > Then those are of course needed for fast construction many terms into
>>> > on Add, but this not really exposed to user's code and it is used
>>> > inside things like expand(). As such, we can provide a special static
>>> > method or function for doing the same. On the other hand, if you
>>> > write:
>>> >
>>> > x + x + x + y + x + x
>>> >
>>> > in Python, then Python itself will call Symbol.__add__ etc., so this
>>> > would work well with our new dispatch.
>>> >
>>> > --
>>> > 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.
>>> > 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.
> 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.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to