Newer
Older
if op == '+': return diff(u, x) + diff(v, x)
elif op == '-' and len(args) == 1: return -diff(u, x)
elif op == '-': return diff(u, x) - diff(v, x)
elif op == '*': return u * diff(v, x) + v * diff(u, x)
elif op == '/': return (v*diff(u, x) - u*diff(v, x)) / (v * v)
elif op == '**' and isnumber(x.op):
return (v * u ** (v - 1) * diff(u, x))
elif op == '**': return (v * u ** (v - 1) * diff(u, x)
+ u ** v * Expr('log')(u) * diff(v, x))
elif op == 'log': return diff(u, x) / u
else: raise ValueError("Unknown op: %s in diff(%s, %s)" % (op, y, x))
def simp(x):
if not x.args: return x
args = map(simp, x.args)
u, op, v = args[0], x.op, args[-1]
if v == ZERO: return u
if u == ZERO: return v
if u == v: return TWO * u
if u == -v or v == -u: return ZERO
if u.op == '-' and len(u.args) == 1: return u.args[0] ## --y ==> y
if v == ZERO: return u
if u == ZERO: return -v
if u == v: return ZERO
if u == -v or v == -u: return ZERO
if u == ZERO or v == ZERO: return ZERO
if u == ONE: return v
if v == ONE: return u
if u == v: return u ** 2
if u == ZERO: return ZERO
if v == ZERO: return Expr('Undefined')
if u == v: return ONE
if u == -v or v == -u: return ZERO
if u == ZERO: return ZERO
if v == ZERO: return ONE
if u == ONE: return ONE
if v == ONE: return u
if u == ONE: return ZERO
else: raise ValueError("Unknown op: " + op)
## If we fall through to here, we can not simplify further
return Expr(op, *args)
def d(y, x):
"Differentiate and then simplify."
#_______________________________________________________________________________
# Utilities for doctest cases
# These functions print their arguments in a standard order
# to compensate for the random order in the standard representation
if t is dict: return pretty_dict(x)
elif t is set: return pretty_set(x)
else: return repr(x)
"""Return dictionary d's repr but with the items sorted.
>>> pretty_dict({'m': 'M', 'a': 'A', 'r': 'R', 'k': 'K'})
"{'a': 'A', 'k': 'K', 'm': 'M', 'r': 'R'}"
>>> pretty_dict({z: C, y: B, x: A})
'{x: A, y: B, z: C}'
return '{%s}' % ', '.join('%r: %r' % (k, v)
for k, v in sorted(d.items(), key=repr))
"""Return set s's repr but with the items sorted.
>>> pretty_set(set(['A', 'Q', 'F', 'K', 'Y', 'B']))
"set(['A', 'B', 'F', 'K', 'Q', 'Y'])"
>>> pretty_set(set([z, y, x]))
'set([x, y, z])'
return 'set(%r)' % sorted(s, key=repr)
def ppsubst(s):
"""Pretty-print substitution s"""
ppdict(s)
def ppdict(d):
print pretty_dict(d)
def ppset(s):
print pretty_set(s)
#________________________________________________________________________
class logicTest: """
### PropKB
>>> kb = PropKB()
>>> kb.tell(A & B)
>>> kb.tell(B >> C)
>>> kb.ask(C) ## The result {} means true, with no substitutions
{}
>>> pl_true(P, {})
>>> pl_true(P | Q, {P: True})
True
# Notice that the function pl_true cannot reason by cases:
True
# The following are tautologies from [Fig. 7.11]:
>>> tt_true("(A <=> B) <=> ((A >> B) & (B >> A))")
>>> tt_true("(A & (B | C)) <=> ((A & B) | (A & C))")
>>> tt_true("(A | (B & C)) <=> ((A | B) & (A | C))")
False
### [Fig. 7.13]
>>> alpha = expr("~P12")
>>> to_cnf(Fig[7,13] & ~alpha)
((~P12 | B11) & (~P21 | B11) & (P12 | P21 | ~B11) & ~B11 & P12)
>>> pl_fc_entails(Fig[7,15], expr('SomethingSilly'))