Newer
Older
withal
a validé
crime_kb = FolKB(
['(American(x) & Weapon(y) & Sells(x, y, z) & Hostile(z)) ==> Criminal(x)', # noqa
'Owns(Nono, M1)',
'Missile(M1)',
'(Missile(x) & Owns(Nono, x)) ==> Sells(West, x, Nono)',
'Missile(x) ==> Weapon(x)',
'Enemy(x, America) ==> Hostile(x)',
'American(West)',
'Enemy(Nono, America)'
]))
withal
a validé
)
"""A simple backward-chaining algorithm for first-order logic. [Fig. 9.6]
KB should be an instance of FolKB, and goals a list of literals. """
def fol_bc_or(KB, goal, theta):
for rule in KB.fetch_rules_for_goal(goal):
lhs, rhs = parse_definite_clause(standardize_variables(rule))
for theta1 in fol_bc_and(KB, lhs, unify(rhs, goal, theta)):
yield theta1
def fol_bc_and(KB, goals, theta):
if theta is None:
pass
elif not goals:
else:
first, rest = goals[0], goals[1:]
for theta1 in fol_bc_or(KB, subst(theta, first), theta):
for theta2 in fol_bc_and(KB, rest, theta1):
yield theta2
# ______________________________________________________________________________
# Example application (not in the book).
# You can use the Expr class to do symbolic differentiation. This used to be
# a part of AI; now it is considered a separate field, Symbolic Algebra.
def diff(y, x):
"""Return the symbolic derivative, dy/dx, as an Expr.
However, you probably want to simplify the results with simp.
>>> diff(x * x, x)
((x * 1) + (x * 1))
"""
if y == x:
return ONE
elif not y.args:
return ZERO
else:
u, op, v = y.args[0], y.op, y.args[-1]
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))
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: {} in diff({}, {})".format(op, y, x))
def simp(x):
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
# ________________________________________________________________________