6
6
at present this is mainly needed for facts.py , feel free however to improve
7
7
this stuff for general purpose.
9
from sympy.core.compatibility import iterable, cmp
9
from __future__ import print_function, division
11
from sympy.core.compatibility import iterable
14
def _fuzzy_group(args, quick_exit=False):
15
"""Return True if all args are True, None if there is any None else False
16
unless ``quick_exit`` is True (then return None as soon as a second False
19
``_fuzzy_group`` is like ``fuzzy_and`` except that it is more
20
conservative in returning a False, waiting to make sure that all
21
arguments are True or False and returning None if any arguments are
22
None. It also has the capability of permiting only a single False and
23
returning None if more than one is seen. For example, the presence of a
24
single transcendental amongst rationals would indicate that the group is
25
no longer rational; but a second transcendental in the group would make the
26
determination impossible.
32
>>> from sympy.core.logic import _fuzzy_group
34
By default, multiple Falses mean the group is broken:
36
>>> _fuzzy_group([False, False, True])
39
If multiple Falses mean the group status is unknown then set
40
`quick_exit` to True so None can be returned when the 2nd False is seen:
42
>>> _fuzzy_group([False, False, True], quick_exit=True)
44
But if only a single False is seen then the group is known to
47
>>> _fuzzy_group([False, True, True], quick_exit=True)
57
if quick_exit and saw_other:
24
75
"""Return True (all True), False (any False) or None.
26
If `a` is an iterable it must not be empty; it
29
80
>>> from sympy.core.logic import fuzzy_and
30
81
>>> from sympy import Dummy
50
a, b = [fuzzy_bool(i) for i in args]
51
if a is True and b is True:
53
elif a is False or b is False:
55
elif (len(args) == 1 and iterable(args[0]) or len(args) > 2):
64
if rv: # this will stop updating if a None is ever trapped
68
raise ValueError('fuzzy_and needs at least 1 argument')
70
return fuzzy_bool(args[0])
105
if rv: # this will stop updating if a None is ever trapped
75
112
Not in fuzzy logic
77
Will return Not if arg is a boolean value, and None if argument
114
Return None if `v` is None else `not v`.
82
119
>>> from sympy.core.logic import fuzzy_not
83
120
>>> fuzzy_not(True)
135
Or in fuzzy logic. Returns True (any True), False (all False), or None
137
See the docstrings of fuzzy_and and fuzzy_not for more info. fuzzy_or is
138
related to the two by the standard De Morgan's law.
140
>>> from sympy.core.logic import fuzzy_or
141
>>> fuzzy_or([True, False])
143
>>> fuzzy_or([True, None])
145
>>> fuzzy_or([False, False])
147
>>> print(fuzzy_or([False, None]))
151
return fuzzy_not(fuzzy_and(fuzzy_not(i) for i in args))
96
154
class Logic(object):
97
155
"""Logical expression"""
98
156
# {} 'op' -> LogicClass
129
187
def __cmp__(a, b):
130
188
if type(a) is not type(b):
131
return cmp( str(type(a)), str(type(b)) )
134
return cmp(a.args, b.args)
194
return (a > b) - (a < b)
136
196
def __str__(self):
137
197
return '%s(%s)' % (self.__class__.__name__, ', '.join(str(a) for a in self.args))
159
219
'%s cannot be in the beginning of expression' % term)
222
if '&' in term or '|' in term:
223
raise ValueError('& and | must have space around them')
162
224
if term[0] == '!':
226
raise ValueError('do not include space after "!"')
163
227
term = Not(term[1:])
165
229
# already scheduled operation, e.g. '&'