Home | Trees | Indices | Help |
|
---|
|
Representations and Inference for Logic (Chapters 7-10) Covers both Propositional and First-Order Logic. First we have four important data types: KB Abstract class holds a knowledge base of logical expressions KB_Agent Abstract class subclasses agents.Agent Expr A logical expression substitution Implemented as a dictionary of var:value pairs, {x:1, y:x} Be careful: some functions take an Expr as argument, and some take a KB. Then we implement various functions for doing logical inference: pl_true Evaluate a propositional logical sentence in a model tt_entails Say if a statement is entailed by a KB pl_resolution Do resolution on propositional sentences dpll_satisfiable See if a propositional sentence is satisfiable WalkSAT (not yet implemented) And a few other functions: to_cnf Convert to conjunctive normal form unify Do unification of two FOL sentences diff, simp Symbolic differentiation and simplification
|
|||
KB A Knowledge base to which you can tell and ask sentences. |
|||
PropKB A KB for Propositional Logic. |
|||
Expr A symbolic mathematical expression. |
|||
PropHornKB A KB of Propositional Horn clauses. |
|||
FolKB A knowledge base consisting of first-order definite clauses >>> kb0 = FolKB([expr('Farmer(Mac)'), expr('Rabbit(Pete)'), ... |
|||
logicTest ### PropKB >>> kb = PropKB() >>> kb.tell(A & B) >>> kb.tell(B >> C) >>> kb.ask(C) ## The result {} means true, with no substitutions {} >>> kb.ask(P) False >>> kb.retract(B) >>> kb.ask(C) False |
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|
|||
_NaryExprTable =
|
|||
test_kb = FolKB(map(expr, ['Farmer(Mac)', 'Rabbit(Pete)', 'Mot
|
|||
A = A
|
|||
B = B
|
|||
C = C
|
|||
F = F
|
|||
FALSE = FALSE
|
|||
G = G
|
|||
ONE = 1
|
|||
P = P
|
|||
Q = Q
|
|||
TRUE = TRUE
|
|||
TWO = 2
|
|||
ZERO = 0
|
|||
__package__ =
|
|||
x = x
|
|||
y = y
|
|||
z = z
|
|
True if every element of seq satisfies predicate. >>> every(callable, [min, max]) 1 >>> every(callable, [min, 3]) 0 |
The argument is a string; convert to a number if possible, or strip it. >>> num_or_str('42') 42 >>> num_or_str(' 42x ') '42x' |
Create an Expr representing a logic expression by parsing the input string. Symbols and numbers are automatically converted to Exprs. In addition you can use alternative spellings of these operators: 'x ==> y' parses as (x >> y) # Implication 'x <== y' parses as (x << y) # Reverse implication 'x <=> y' parses as (x % y) # Logical equivalence 'x =/= y' parses as (x ^ y) # Logical disequality (xor) But BE CAREFUL; precedence of implication is wrong. expr('P & Q ==> R & S') is ((P & (Q >> R)) & S); so you must use expr('(P & Q) ==> (R & S)'). >>> expr('P <=> Q(1)') (P <=> Q(1)) >>> expr('P & Q | ~R(x, F(x))') ((P & Q) | ~R(x, F(x))) |
returns the list of literals of logical expression s. >>> literals(expr('F(A, B)')) [F(A, B)] >>> literals(expr('~F(A, B)')) [~F(A, B)] >>> literals(expr('(F(A, B) & G(B, C)) ==> R(A, C)')) [F(A, B), G(B, C), R(A, C)] |
returns the set of variables in logical expression s. >>> ppset(variables(F(x, A, y))) set([x, y]) >>> ppset(variables(expr('F(x, x) & G(x, y) & H(y, z) & R(A, z, z)'))) set([x, y, z]) |
returns True for exprs s of the form A & B & ... & C ==> D, where all literals are positive. In clause form, this is ~A | ~B | ... | ~C | D, where exactly one clause is positive. >>> is_definite_clause(expr('Farmer(Mac)')) True >>> is_definite_clause(expr('~Farmer(Mac)')) False >>> is_definite_clause(expr('(Farmer(f) & Rabbit(r)) ==> Hates(f, r)')) True >>> is_definite_clause(expr('(Farmer(f) & ~Rabbit(r)) ==> Hates(f, r)')) False |
Use truth tables to determine if KB entails sentence alpha. [Fig. 7.10] >>> tt_entails(expr('P & Q'), expr('Q')) True |
Return True if the propositional logic expression is true in the model, and False if it is false. If the model does not specify the value for every proposition, this may return None to indicate 'not obvious'; this may happen even when the expression is tautological. |
Convert a propositional logical sentence s to conjunctive normal form. That is, of the form ((A | ~B | ...) & (B | C | ...) & ...) [p. 215] >>> to_cnf("~(B|C)") (~B & ~C) >>> to_cnf("B <=> (P1|P2)") ((~P1 | B) & (~P2 | B) & (P1 | P2 | ~B)) >>> to_cnf("a | (b & c) | d") ((b | a | d) & (c | a | d)) >>> to_cnf("A & (B | (D & E))") (A & (D | B) & (E | B)) |
Change >>, <<, and <=> into &, |, and ~. That is, return an Expr that is equivalent to s, but has only &, |, and ~ as logical operators. >>> eliminate_implications(A >> (~B << C)) ((~B | ~C) | ~A) |
Rewrite sentence s by moving negation sign inward. >>> move_not_inwards(~(A | B)) (~A & ~B) >>> move_not_inwards(~(A & B)) (~A | ~B) >>> move_not_inwards(~(~(A | ~B) | ~~C)) ((A | ~B) & ~C) |
Given a sentence s consisting of conjunctions and disjunctions of literals, return an equivalent sentence in CNF. >>> distribute_and_over_or((A & B) | C) ((A | C) & (B | C)) |
Create an Expr, but with an nary, associative op, so we can promote nested instances of the same op up to the top level. >>> NaryExpr('&', (A&B),(B|C),(B&C)) (A & B & (B | C) & B & C) |
Return a list of the conjuncts in the sentence s. >>> conjuncts(A & B) [A, B] >>> conjuncts(A | B) [(A | B)] |
Return a list of the disjuncts in the sentence s. >>> disjuncts(A | B) [A, B] >>> disjuncts(A & B) [(A & B)] |
Propositional Logic Resolution: say if alpha follows from KB. [Fig. 7.12] |
Return all clauses that can be obtained by resolving clauses ci and cj. >>> for res in pl_resolve(to_cnf(A|B|C), to_cnf(~B|~C|F)): ... ppset(disjuncts(res)) set([A, C, F, ~C]) set([A, B, F, ~B]) |
Use forward chaining to see if a HornKB entails symbol q. [Fig. 7.14] >>> pl_fc_entails(Fig[7,15], expr('Q')) True |
Check satisfiability of a propositional sentence. This differs from the book code in two ways: (1) it returns a model rather than True when it succeeds; this is more useful. (2) The function find_pure_symbol is passed a list of unknown clauses, rather than a list of all clauses and the model; this is more efficient. >>> ppsubst(dpll_satisfiable(A&~B)) {A: True, B: False} >>> dpll_satisfiable(P&~P) False |
Find a symbol and its value if it appears only as a positive literal (or only as a negative) in clauses. >>> find_pure_symbol([A, B, C], [A|~B,~B|~C,C|A]) (A, True) |
A unit clause has only 1 variable that is not bound in the model. >>> find_unit_clause([A|B|C, B|~C, A|~B], {A:True}) (B, False) |
The symbol in this literal (without the negation). >>> literal_symbol(P) P >>> literal_symbol(~P) P |
Unify expressions x,y with substitution s; return a substitution that would make x,y equal, or None if x,y can not unify. x and y can be variables (e.g. Expr('x')), constants, lists, or Exprs. [Fig. 9.1] >>> ppsubst(unify(x + y, y + C, {})) {x: y, y: C} |
Copy the substitution s and extend it by setting var to val; return copy. >>> ppsubst(extend({x: 1}, y, 2)) {x: 1, y: 2} |
Substitute the substitution s into the expression x. >>> subst({x: 42, y:0}, F(x) + y) (F(42) + 0) |
Inefficient forward chaining for first-order logic. [Fig. 9.3] KB is an FOLHornKB and alpha must be an atomic sentence. |
Replace all the variables in sentence with new variables. >>> e = expr('F(a, b, c) & G(c, A, 23)') >>> len(variables(standardize_apart(e))) 3 >>> variables(e).intersection(variables(standardize_apart(e))) set([]) >>> is_variable(standardize_apart(expr('x'))) True |
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. >>> test_ask('Farmer(x)') ['{x: Mac}'] >>> test_ask('Human(x)') ['{x: Mac}', '{x: MrsMac}'] >>> test_ask('Hates(x, y)') ['{x: Mac, y: Pete}'] >>> test_ask('Loves(x, y)') ['{x: MrsMac, y: Mac}', '{x: MrsRabbit, y: Pete}'] >>> test_ask('Rabbit(x)') ['{x: MrsRabbit}', '{x: Pete}'] |
Return the substitution which is equivalent to applying s2 to the result of applying s1 to an expression. >>> s1 = {x: A, y: B} >>> s2 = {z: x, x: C} >>> p = F(x) & G(y) & expr('H(z)') >>> subst(s1, p) ((F(A) & G(B)) & H(z)) >>> subst(s2, p) ((F(C) & G(y)) & H(x)) >>> subst(s2, subst(s1, p)) ((F(A) & G(B)) & H(x)) >>> subst(subst_compose(s1, s2), p) ((F(A) & G(B)) & H(x)) >>> subst(s1, subst(s2, p)) ((F(C) & G(B)) & H(A)) >>> subst(subst_compose(s2, s1), p) ((F(C) & G(B)) & H(A)) >>> ppsubst(subst_compose(s1, s2)) {x: A, y: B, z: x} >>> ppsubst(subst_compose(s2, s1)) {x: C, y: B, z: A} >>> subst(subst_compose(s1, s2), p) == subst(s2, subst(s1, p)) True >>> subst(subst_compose(s2, s1), p) == subst(s1, subst(s2, p)) True |
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)) >>> simp(diff(x * x, x)) (2 * x) |
Print the dictionary d. Prints a string representation of the dictionary with keys in sorted order according to their string representation: {a: A, d: D, ...}. >>> 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}' |
Print the set s. >>> 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])' |
|
test_kb
|
Home | Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Wed Aug 1 18:44:31 2012 | http://epydoc.sourceforge.net |