There are two places where I see a hard coded Add that might be a problem.

One in _create_evalf_table() in evalf.py, but commenting out the Add line 
doesn't create an infinite recursion.

The more likely place is in Expr.as_independent().  Clearly, that gives a 
different result for Add and Add2.

In [9]: Add(3,2, evaluate=False).as_independent(Symbol, AppliedUndef)
Out[9]: (5, 0)

In [10]: Add2(3,2, evaluate=False).as_independent(Symbol, AppliedUndef)
Out[10]: (2 + 3, 1)

OK, just tried to write a fix, but as I don't really understand what 
as_independent does, I'm not confident of the fix.  Here's a pull request 
that at least gives the right answer for the one case of as_independent 
that I checked and removes the infinite loop for Add2.

In [3]: Add2(3,2, evaluate=False).as_independent(Symbol, AppliedUndef)
Out[3]: (5, 0)

In [4]: Add2(3,2, evaluate=False).evalf()
Out[4]: 5.00000000000000

https://github.com/sympy/sympy/pull/10126

Sorry, haven't written any tests, yet.  I'm out of time that I can spend on 
this for now. :)

Duane






On Monday, November 9, 2015 at 12:16:17 PM UTC-6, Aaron Meurer wrote:
>
> For most classes there isn't, but there can be. Using func instead of 
> type() allows objects to have a function that isn't its literal Python 
> class.  This is necessary, for instance, if you want to allow the 
> function to also be usable as an expression, since in that case it 
> would also have to be a Python object (not a class). 
>
> An example of this are the predicate objects, like Q.positive. We want 
> to be able to use both Q.positive and Q.positive(x) in logic 
> expressions. If Q.positive were the type() of Q.positive(x), this 
> would be impossible, because then Q.positive couldn't be an instance 
> of Basic. 
>
> So instead, it has its own type, and the .func is set appropriately: 
>
> In [20]: type(Q.positive(x)) 
> Out[20]: sympy.assumptions.assume.AppliedPredicate 
>
> In [21]: Q.positive(x).func 
> Out[21]: Q.positive 
>
> Ideally we would like to do the same thing with functions as well 
> (https://github.com/sympy/sympy/issues/4787) so that it will be 
> possible to write things like cos + sin, and other "operator" like 
> expressions. sin + cos may end up not being a good idea, but as the 
> issue notes, something like D(f), where D is some kind of differential 
> operator, would be possible in this case (right now it isn't really 
> because f isn't an instance of Basic, so you can't just have D(f).args 
> == (f,)). 
>
> func has also been suggested as the way around issues with classes 
> that want to put non-Basic things in their args (particularly strings, 
> like with MatrixSymbol). Instead of MatrixSymbol('x', n, n).args == 
> ('x', n, n) as it is now, which is bad and breaks a lot of things 
> (because 'x' is not an instance of Basic), we would have 
> MatrixSymbol('x', n, n).args == (n, n) and MatrixSymbol('x', n, 
> n).func would be a special object that contains the 'x', which can 
> recreate the original MatrixSymbol('x', n, n). 
>
> Aaron Meurer 
>
> On Mon, Nov 9, 2015 at 12:07 PM, Francesco Bonazzi 
> <[email protected] <javascript:>> wrote: 
> > By the way, is there a real difference between type(self)(*args) and 
> > self.func(*args) ? 
> > 
> > On Monday, 9 November 2015 18:15:10 UTC+1, Aaron Meurer wrote: 
> >> 
> >> That's definitely a bug. Subclassing any class without changing 
> >> anything shouldn't break anything. There are unfortunately several 
> >> instances of this issue (see 
> >> https://github.com/sympy/sympy/issues/6751). Probably somewhere in 
> >> that code path something is referencing Add directly instead of using 
> >> self.func, or doing a type comparison without using isinstance. 
> >> 
> >> Aaron Meurer 
> >> 
> >> On Mon, Nov 9, 2015 at 10:48 AM, Duane Nykamp <[email protected]> 
> wrote: 
> >> > OK, I'm pretty sure this is a bug.  I don't have to change Add at all 
> to 
> >> > get 
> >> > this infinite recursion, just create any subclass 
> >> > 
> >> > In [7]: Add(3,3,evaluate=False).evalf() 
> >> > Out[7]: 6.00000000000000 
> >> > 
> >> > In [8]: class Add2(Add): 
> >> >    ...:     pass 
> >> >    ...: 
> >> > 
> >> > In [9]: Add2(3,3,evaluate=False).evalf() 
> >> > RuntimeError: maximum recursion depth exceeded 
> >> > 
> >> > I can't figure out where the code is treating Add and its identical 
> >> > subclass 
> >> > Add2 differently. 
> >> > 
> >> > Duane 
> >> > 
> >> > -- 
> >> > 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. 
> >> > To view this discussion on the web visit 
> >> > 
> >> > 
> https://groups.google.com/d/msgid/sympy/60272dc0-8bf7-47db-83a9-01a840180943%40googlegroups.com.
>  
>
> >> > 
> >> > For more options, visit https://groups.google.com/d/optout. 
> > 
> > -- 
> > 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] <javascript:>. 
> > To post to this group, send email to [email protected] 
> <javascript:>. 
> > Visit this group at http://groups.google.com/group/sympy. 
> > To view this discussion on the web visit 
> > 
> https://groups.google.com/d/msgid/sympy/fe2324dd-75b8-4f14-a21b-f9fcb192b2c5%40googlegroups.com.
>  
>
> > 
> > For more options, visit https://groups.google.com/d/optout. 
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/45fdd203-80bd-4b3a-8b71-30140f41cb40%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to