On Fri, Jul 22, 2011 at 3:19 PM, Ronan Lamy <[email protected]> wrote:
> Le vendredi 22 juillet 2011 à 20:57 +0100, Tom Bachmann a écrit :
>> The relevant code making this assumption sympy/integrals/risch.py, line 331.
>>
> Though the code is far from easy to understand, it seems that the inner
> function was never meant to receive Tuples or even meijerg objects.
> Anyway, I guess you should replace the elif line with 'elif
> isinstance(g, Expr) and not g.is_Atom:' or perhaps 'elif not g.is_Atom
> and g.args:'.
>
>> On 22.07.2011 20:54, Aaron Meurer wrote:
>> > Hi everyone.
>> >
>> > Tom has this commit in his gsoc-2 branch
>> > https://github.com/ness01/sympy/commit/43877ee46e6b4095e2667df4636c3a14b4b820d1.
>> >   In it, he defines Tuple().is_Atom to be True, i.e., the empty Tuple.
>> >
>> > Is this problematic, since isinstance(Tuple(), Atom) would still be
>> > False?
>
> Yes. obj.is_Atom should be the same as isinstance(obj, Atom).
>
>> Apparently some code relies on objects that cannot be
>> > traversed further through .args to have is_Atom == True.  Is this a
>> > reasonable assumption for that code to make?
>
> is_Atom implies that there are no args, but assuming the converse is
> problematic, as this issue shows. But the most unreasonable assumption
> here is to assume it's safe to recurse blindly down the args without
> considering their meaning.
>
>>   And if the answers to
>> > these questions are yes, then can it be setup through some kind of
>> > metaclass logic to make Tuple() an instance of Atom but not Tuple(1),
>> > for example?
>
> Metaclass trickery isn't needed here. If there really is a good reason
> to make Tuple() an Atom, we should just create a singleton EmptyTuple
> class inheriting from Tuple and Atom. But this special case doesn't look
> special enough.
>

Ah, I see.

Well, more and more objects are containing Tuples as part of the args
these days with the advent of these Bessel and Meijer G type
functions.  So it will become more of an issue, not less.  I guess we
just need to answer the question of whether we want to guarantee that
a Basic object with no args is an Atom or not.  Just one example makes
it hard to consider.  I know that simple rebuilding, like
Obj(*[func(i) for i in obj.args]) will just work for objects with
empty .args because the list comprehension will be empty.

Now that I think about it, Atom has a use beyond telling the user that
it has empty .args.  An Atom cannot be rebuilt with
obj.func(*obj.args).  For example, Rational(2, 3).args is () and .func
is just Rational, so you have to make sure that when rebuilding an
expression that when you get to an Atom that you just include it,
rather than trying to rebuild it.  This would not be the case for
Tuple(), though, since Tuple(*()) == Tuple().  So maybe it shouldn't
be an Atom.  Or can you think of other arguments?

Aaron Meurer

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