Here is another idea that might help:

What if we *always* mapped the *args logic for operators like Mul/Add
to the binary ones:

if len(args)==2:
  self.dispatch(*args)
else:
  return Mul(Mul(args[0],args[1]),args[2]) etc

Then we could focus on the rules and patterns for binary versions.
This doesn't solve the issue of needing pattern matching...

On Wed, Jul 3, 2013 at 2:19 PM, Brian Granger <[email protected]> wrote:
> On Wed, Jul 3, 2013 at 1:42 PM, Ondřej Čertík <[email protected]> wrote:
>> 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.
>
> For example take a quantum time evolution operator exp(-I*t*H).  What
> if I wanted to develop custom logic for that operator.  Simply
> matching on type type (exp) won't work.  You need to be able to say:
>
> exp(-I*Numer(x_)*HermitianOperator(y_))
>
> That requires pattern matching...
>
>>
>>
>> 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)
>
> But Mul is not a binary operator in SymPy - we could make it so and
> build the overall *args version by repeatedly calling the binary
> version.  That would be nice... and would somewhat help our
> situation...
>
>> 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.
>>
>>
>
>
>
> --
> Brian E. Granger
> Cal Poly State University, San Luis Obispo
> [email protected] and [email protected]



-- 
Brian E. Granger
Cal Poly State University, San Luis Obispo
[email protected] and [email protected]

-- 
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