Opened 6 years ago
Last modified 5 years ago
#17700 new defect
wrong symbolic results in case the answer is not known
Reported by: | jakobkroeker | Owned by: | |
---|---|---|---|
Priority: | critical | Milestone: | sage-6.8 |
Component: | symbolics | Keywords: | |
Cc: | eviatarbach, tmonteil, slelievre, vdelecroix | Merged in: | |
Authors: | Reviewers: | ||
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | pynac-0.3.9.3/-0.4.3 | Stopgaps: | todo |
Description (last modified by )
A failing example is taken from
http://ask.sagemath.org/question/10388/testing-inequalities-in-sage/
var('a','b') bool( abs(a+b) <= abs(a) + abs(b) ) # False, expected True or 'Unknown' assert (not False == bool( abs(a+b) <= abs(a) + abs(b) ) ) #fails
The documentation of bool() says "Returns True when the argument x is true, False otherwise."
Formally this includes returning False in case the answer is unknown and it seems that bool() was specified to behave like it does. But I find that is very unfortunate and even improving the documentation (explicitly mention the 'answer is unknown' case) is not sufficient.
see also discussion at https://groups.google.com/d/msg/sage-devel/vNxnHSeRBW4/0OpeL0yv9YUJ
In that thread the exception variant is preferred in case of 'don't know'
Please also take into consideration Tristate variants ( A sandbox for a Tristate class: https://github.com/jakobkroeker/Tristate.py )
See also https://groups.google.com/forum/?hl=en#!topic/sage-devel/4DUsgt670MA
Change History (12)
comment:1 Changed 6 years ago by
- Cc tmonteil added
comment:2 Changed 6 years ago by
comment:3 Changed 6 years ago by
I'll gladly do a review of this ticket.
comment:4 Changed 6 years ago by
- Description modified (diff)
comment:5 Changed 6 years ago by
- Description modified (diff)
comment:6 Changed 6 years ago by
- Milestone changed from sage-6.5 to sage-6.7
Btw., also the coercion framework occasionally leads to "surprising" results (because silently False
is returned upon comparison when no coercion can be established, such that for example a == b and a == c
doesn't imply b == c
). This and similar has been discussed on sage-devel a couple of times.
comment:7 Changed 6 years ago by
The ticket is about symbolics so let's get concrete. It happens that at the moment I'm implementing more logic affecting comparisons/relations/zero tests of expressions in Pynac. The decision process for the logic in Sage is:
Expression.__nonzero__()
is called on input of bool
. __nonzero__
is the one that should throw an exception for unknown results. In __nonzero__
,
- first the relations of constants are decided
- Pynac's
relational_to_bool
is called (relational::safe_bool()
), it does:- relations with one or two infinities; any result gets returned by
__nonzero__
right away - if l.h.s - r.h.s is a Python object (other than
Expression
) compare it to zero, i.e., delegate to the resp. class - else if relation is >= or <= use positive flag of (l.h.s - r.h.s) or its negative to decide (Pynac-0.3.9.3/0.4.3)
- relations with one or two infinities; any result gets returned by
- the previous result may now get changed in case of not-equal; already here Maxima may be called (I think this is wrong, Maxima should always be the last resort)
- if no assumptions are needed now is time for
test_relation
which has some detailed logic and uses interval fields to disprove relations ("interval fields never return false positives"); it already has tristate logic by returningNotImplemented
if unsure - if the previous neither returns
True/False
return whatsymbolic/relation.py:test_relation_maxima()
returns- the relation is tested and any
True
is returned immediately - simplification is attempted before returning the final
True/False
- the relation is tested and any
EDIT: __nonzero__
is not called by Pynac
EDIT: add info about upcoming Pynac snippet
comment:8 Changed 6 years ago by
- Dependencies set to pynac-0.3.9.3/-0.4.3
- Milestone changed from sage-6.7 to sage-6.8
In https://github.com/pynac/pynac/issues/80 we implement multistate for item 2 above. The Sage part raises a TypeError
with text Undecidable relation: ...
if Pynac returns undecidable
and continues on with item 3/4 in case of not implemented
.
comment:9 Changed 6 years ago by
The second issue this ticket depends on concerns the Maxima interface in item 5. There is e.g.:
sage: from sage.symbolic.relation import test_relation_maxima sage: test_relation_maxima(I>0) False
because in Maxima
(%i8) is(%i>0); (%o8) false
so the 'false' result should raise a NotImplementedError
in __nonzero__
because Maxima does not distinguish between false
, known undecidable
, and unknown
. This produces hundreds of doctest fails in symbolics
alone.
Moreover, trying to snatch this decision functionality from Maxima presupposes an independent assumption framework.
EDIT: I is %i in Maxima
comment:10 Changed 6 years ago by
- Cc slelievre vdelecroix added
comment:11 Changed 5 years ago by
I started doing some work on this. Since Sage already has an Unknown
object for representing indeterminate truth values, I thought we could adapt it for use here. Ticket #20920 makes some changes to Unknown
to raise an error when attempting to evaluate its truth value with __nonzero__
, as well as adding an Undecidable
object.
comment:12 Changed 5 years ago by
Great. See also #19040.
Thanks for opening this ticket! I think this is a huge problem in Sage symbolics.
I can't remember what I did to change the behaviour so that when a comparison is made and the result can't be determined it raises an exception instead of returning
False
; I'll try to look into it this weekend.I like the idea of having a three-valued logic (https://en.wikipedia.org/wiki/Three-valued_logic); unfortunately Python makes this very difficult, as the
Tristate
class shows. There does not seem to be an elegant solution, so I wonder if it's not just best to stick with exceptions.