On Mar 30, 2010, at 4:26 AM, jegerjensen wrote:

> Am I right that you have concluded that bool() of a relational should
> always return True?
> That would allow some rather weird things:
> 
> In [1]: if x < y and x > y:
>   ...:     print "I would not expect to see this printed"
> 
But why would you want to do this?  "if x < y" doesn't make sense if x and y 
are symbols.

> Today I get no output from this and it would surprise me to get
> anything else.
> 
> Instead I propose that we just agree that bool(x<y) has nothing to do
> with the mathematical relation, but will completely hand over the
> relation to python for evaluation.  

But then we loose the shortcut x < y => Lt(x, y). 

> (Isn't this the present
> behavior?)  If we accept this rule, Out[65] and Out[66] are not
> inconsistent, but shows rather how python works internally.  The
> language reference states that "objects of different types always
> compare unequal, and are ordered consistently but arbitrarily.
> 
This will change in Python 3.  There, objects have to be the same type to be 
compared.  

Aaron Meurer

> If on the other hand you want to test the mathematical expression, you
> should use ask() as you have discussed, or maybe a method like
> Relational.is_valid().
> 
> Øyvind
> 
> On 27 Feb, 11:16, Brian Granger <[email protected]> wrote:
>> Aaron,
>> 
>> Thanks for looking at this.
>> 
>> I'm still working out how the new assumptions work myself.  They are not
>> 
>>> fully merged in yet, so I don't know how much will actually work.  I guess
>>> you would just have to try it.  We may need to finish merging the
>>> assumptions in order to full sort out inequalities (ironically, we need
>>> assumptions to do inequalities, but we also need to ability to solve
>>> inequalities to have some kinds of assumptions).
>> 
>> OK.  Hopefully others can fill in some details about the status of the new
>> assumptions system.
>> 
>>> Yes, Ask(whatever, assumptions) will return True if whatever is true under
>>> assumptions, False if it is false, and None if it is undetermined.  Or at
>>> least it is supposed to, again, the system is not fully merged in yet, so
>>> there could be problems.  This is to become the standard interface.  I
>>> believe your concerns were one of the reasons for creating the new
>>> assumptions system in the first place.
>> 
>> Nice, that sounds like it should address this issue exactly.
>> 
>> I agree that that __nonzero__ is a mess.  Based on your discussion below, I> 
>> think the inequalities should automatically return True or False if it is
>>> number < number, and if it stays as an inequality class, then the bool
>>> should just be false (i.e., replace __nonzero__ with simply "return True").
>> 
>> Yes, __nonzero__ should just return True to be consistent with how it is
>> handled elsewhere in sympy.  I also agree for numbers.  The only case the
>> this doesn't cover is other object that have well defined < and > that
>> should be simplified to True or False when compared.
>> 
>>> I think I figured out most of your problems.  See the attached patch for a
>>> demonstration (it needs cleaning up, and I only did StrictInequality).  See
>>> also the commit message.
>> 
>> Nice, this will help me to get going.  If I have a chance this weekend I
>> will continue the work you started and report back.
>> 
>> Thanks Aaron!
>> 
>> Cheers,
>> 
>> Brian
>> 
>>> --
>>> 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] <sympy%[email protected]>.
>>> For more options, visit this group at
>>> http://groups.google.com/group/sympy?hl=en.
>> 
>>> Someone else will need to answer your question on how far we are with the
>>> assumptions system.  I haven't been working on it.
>> 
>>> Aaron Meurer
>>> On Feb 26, 2010, at 9:25 PM, Brian Granger wrote:
>> 
>>> Aaron,
>> 
>>> Thanks for the thoughtful replies.  As I have been looking at this further,
>>> I think the core question is this:  how are Sympy objects converted to
>>> bools?
>> 
>>> Is seem that there are two notions:
>> 
>>> * The primitive notion of truth built into python itself.  This is handled
>>> by Python in the __nonzero__ method.  The pattern followed in 90% of Sympy
>>> is that __nonzero__ returns True unless the object is Zero.  In this concept
>>> of truth is makes sense to ask the truth value of single objects:
>> 
>>> bool(x)
>>> bool(1)
>>> etc.
>> 
>>> * The mathematical idea related to whether or not a relational equation is
>>> satisfied:
>> 
>>> 1 < 0
>>> x < y
>>> 2*x + y == 0
>> 
>>> To me it seems that these two types of truth concepts should be
>>> *completely* orthogonal.  What are the consequences of this?
>> 
>>> 1. Converting a relational equation to a boolean using bool [bool(x<0)] is
>>> not asking the mathematical question "is x less than 0".  It is asking the
>>> the more primitive question of "is this a nonzero python object".
>> 
>>> 2. There must be a different API for testing if a relational equation is
>>> satisfied.  I don't see this separate interface.  Maybe it is the assumption
>>> system, but assumptions seem to be different conceptually than equations.
>>> But I don't really understand how assumptions work in sympy.  Whatever this
>>> other API is, it needs to be capable of giving the following answers:
>> 
>>> * It is satisfied
>>> * It is not satisfied
>>> * It is undetermined.
>> 
>>> The current situation is lacking in two respects:
>> 
>>> * The classes in relational (Equality, Inequality, StrictInequality, etc.)
>>> violate this clean separation of truth types by having __nonzero__ method
>>> that combines and confuses the two types.  You see things like this:
>> 
>>>     def __nonzero__(self):
>>>         if self.lhs.is_comparable and self.rhs.is_comparable:
>>>             if self.lhs.is_Number and self.rhs.is_Number:
>>>                 return self.lhs < self.rhs
>>>             return self.lhs.evalf()<self.rhs.evalf()
>>>         return self.lhs.compare(self.rhs)==-1
>> 
>>> * There is no standard interface for asking about the second (relational
>>> equation) type of truth.  This is probably why Relational classes are
>>> confusing the two.
>> 
>>> I tried commenting out the __nonzero__ method in Relational, but a good
>>> number of tests fail - some with a RuntimeError saying the recursion limit
>>> has been reached.
>> 
>>> I am not sure how to proceed.  What is the most up to date description of
>>> the assumption system in sympy?  Is the new assumption system in place and
>>> the recommended approach.
>> 
>>> Cheers,
>> 
>>> Brian
>> 
>>> On Fri, Feb 26, 2010 at 7:11 PM, Aaron S. Meurer <[email protected]>wrote:
>> 
>>>> On Feb 26, 2010, at 5:40 PM, Brian Granger wrote:
>> 
>>>> Aaron,
>> 
>>>> Thanks for the response...replies inline
>> 
>>>>> In [66]: bool(x<0)
>>>>>> Out[66]: False
>> 
>>>>>> This is obviously not consistent and it a bug in Relational.__nonzero__
>> 
>>>>> Yes, let's make any SymPy expression return True if and only if it is not
>>>>> the object S.Zero (or maybe also some empty containers, like Matrix([])).
>> 
>>>> Yep and that is what Basic.__nonzero__ does.
>> 
>>>>> I'm not sure what to do about the relational (see below).
>> 
>>>> Right.
>> 
>>>>>> Relational classes don't properly evaluate to booleans
>>>>>> ======================================================
>> 
>>>>>> Consider these examples:
>> 
>>>>>> In [67]: Eq(0,0)
>>>>>> Out[67]: 0 == 0
>> 
>>>>>> In [68]: Ge(1,0)
>>>>>> Out[68]: 0 <= 1
>> 
>>>>>> Obviously, these should resolve to booleans. You may think, why
>>>>> wouldn't
>>>>>> you just do 0==0 or 1<0? But consider this:
>> 
>>>>> Just to be clear we overload __lt__, etc. to return the Le() class, but
>>>>> == is just the simple equality testing (not the Eq class).  This is fine,
>>>>> but like you say, there needs to still be a way to do actual comparison.
>>>>>  The problem I have seen is that it likes to turn things into booleans 
>>>>> that
>>>>> don't make sense that way, other than being non-empty.  For example, the 
>>>>> x<0
>>>>> above.
>> 
>>>> Right.
>> 
>>>>> Another thing, automatic evaluation should proceed on a SymPy object only
>>>>> if three conditions are met:
>>>>> 1. The evaluation will always make the object simpler.
>>>>> 2. The evaluation is very cheap in every case.
>>>>> 3. The evaluation is so trivial that no one will ever not want it done.
>> 
>>>>> For example, we auto-simplify exp(x)*exp(x) to exp(2*x), but we leave
>>>>> exp(x)*exp(y) alone, because if we auto-combined it, it would be 
>>>>> impossible
>>>>> to actually get exp(x)*exp(y) instead of exp(x + y) (things used to be 
>>>>> this
>>>>> way back in SymPy 0.6.4 until I spent a very headacheful few weeks 
>>>>> changing
>>>>> it last summer).
>> 
>>>>> (1) is clearly the case for turning inequalities into booleans.  (2) will
>>>>> only be true for the simple case of number < number.
>> 
>>>> I could imagine other mathematical objects that have a clear concept of <
>>>> and > and that are cheap to find.
>> 
>>>> Yes.  I think we are simplifying things like x < x + 1 right now too.  But
>>>> there is also (3) to consider for that.
>> 
>>>>> Otherwise, even if the assumption for Ask(x - y, Q.positive) is True for
>>>>> x > y, we should leave it alone in Gt.__new__ and leave the work to
>>>>> refine().  Actually, even if this were cheap, I would still want to leave 
>>>>> it
>>>>> alone because of (3).
>> 
>>>> Yes, I agree that refine should be used in this cases.
>> 
>>>>> Also, should we prevent bool(relational) from working otherwise, much
>>>>> like the TypeError you get when you do 1j < 1?
>> 
>>>> The problem with this is that there is little different between bool(x)
>>>> and bool(x<0).
>> 
>>>>>  I would rather have bool(x<y) raise an error than mislead me by
>>>>> returning True (misleading in the sense that bool(x>y) would also be 
>>>>> True).
>> 
>>>> But it would also be misleading that bool(2*x) is True, but bool(x<0)
>>>> raises an exception.
>> 
>>>> I guess the problem is what if you want to do an actual comparison.  We
>>>> override <, >, etc., but that is what you would normally use in an if
>>>> statement, though I guess you should really be making a call to Ask().  So
>>>> as long as this is clear, it shouldn't be a problem either way.
>> 
>>>>> Semantically speaking, relational.__nonzero__ should be True unless the
>>>>> relational is explicitly False, and relational.__bool__ should be either 
>>>>> the
>>>>> explicit truth value of the relational or raise TypeError if there is 
>>>>> none,
>>>>> but I do not know the actual implementation difference between these two 
>>>>> in
>>>>> Python.
>> 
>>>> Yes, there is this issue as well.
>> 
>>>>>> In [69]: e = Ge(x,0)
>> 
>>>>>> In [70]: e.subs(x,1)
>>>>>> Out[70]: 0 <= 1    # Just Ge(1,0)!
>> 
>>>>>> Thus. it is common and easy to get Relational classes that should
>>>>> evaluate to
>>>>>> a boolean but don't.  This behavior also affects boolean logic classes
>>>>>> like And/Or, etc. as well as Interval:
>> 
>>>>>> In [71]: e = And(x>0,x<1)
>> 
>>>>>> In [72]: e.subs(x,0.5)
>>>>>> Out[72]: And(0 < 0.5, 0.5 < 1)
>> 
>>>>>> The problem is that the __new__ method of Relational does NOT actually
>>>>>> try to compare the lhs and rhs.  That is, Ge.__new__(lhs, rhs) doesn't
>>>>> actually
>>>>>> try lhs >= rhs.  But, we can't have it try that or it will generate an
>>>>>> infinite loop!  Resolving this will be quite subtle.
>> 
>>>>> This should at least work with refine:
>> 
>>>>> In [17]: refine(e.subs(x,0.5))
>>>>> Out[17]: And(0 < 0.5, 0.5 < 1)
>> 
>> ...
>> 
>> les mer »
> 
> -- 
> 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