Sep 22
propositional logic
We'll discuss the material in chapter 7,
which I asked you to read :
- What is propositional logic (as opposed to first order logic) ?
- What is a well formed expression ?
- What does it mean that an expression (or expression) "entails" another ? Example?
- Conjuctive normal form : (A or B or not C) and (C or D)
- Any expression can be put in that form.
- Show how.
- Discuss the "resolution procedure" :
- Given (1) a KB (knowledge base) in CNF (conjuctive normal form)
- And (2) a proposition S
- We want to see if KB entails S.
- 1st : add (not S) to KB.
- Then loop :
- Find two clauses with (stuff1 ... Z) (stuff2 ... not Z).
- Add new clause to KB : (stuff1 ... stuff2).
- Repeat until either
- i) nothing else to do (search fails) or
- ii) an empty clause is reached, which is false, which is a contradition, which establishes S.
That's the main idea of the chapter.
The fine print :
- Horn clause : at most one "positive" term per clause.
- The idea is that (A and B and C implies D) is (not A or not B or not C or D) which is of this form.
- ... and it turns out that makes the inference search faster (linear time)
The horn search techniques are
- forward chaining i.e. (A, B, A and B implies C) means you can "chain" to C.
- starts from known facts, works toward a goal
- the problem with this approach is that in a large KB there are many, many starting facts.
- backward chaining i.e. (want C, have A and B implies C, so (need A), (need B)).
AIMA logic.py
This implements some of the algorithms described in the text.
The logic expressions are built on an Expr() object,
using python operations including
>> implies
| or
& and
~ not
A, B, C, D, E, F, G, P, Q, x, y, z = map(Expr, 'ABCDEFGPQxyz')
so for example exercise 7.17 becomes
>> from logic import * # AIMA routines
>> kb = PropKB() # propositional logic, general but slow
>> kb.tell( (A | B) & (~A | C) & (~B | D) & (~C | G) & (~D | G) )
>> kb.ask(G)
{} # meaning "nothing is required to make this true"
>> kb.ask(E)
False
>> kb.clauses
[(A | B), (~A | C), (~B | D), (~C | G), (~D | G)]
>> kb.tell(A >> B) # It will convert to CNF
>> kb.clauses
[(A | B), (~A | C), (~B | D), (~C | G), (~D | G), (B | ~A)]
Are we having fun yet?
class exercises
Put this into CNF form: (A → B) and (B → C).
Use the resolution procedure to infer (A → C).
See if we can encode some of these ...
The PropDefiniteKB does forward chaining.
But it only accepts clauses in
one of these forms : 'A', 'A >> B', '(A & B & C) >> D'.
(It doesn't like 'A | ~B'. Go figure.)
aside
Typing these may be awkward, but in these days of utf-8
you can nearly always cut'n'paste ...
from wikipedia: list of logic symbols
⇒ → implies
≡ ⇔ ↔ iff (if and only if)
¬ ~ ! not
∧ & and
∨ || or
∀ for all
∃ there exists
⊢ is provable
⊨ entails
T true
F false
chapter 7 powerpoint ?
summary :
- wumpus world translation to propositions ; why 1st order will be better
- percepts : (stench, breeze, glitter, bump, scream)
- horn form : CNF with only one positive per clause, e.g. (~A or ~B or C)
- so each clause has only one piece on right, e.g. (A & B) => C
- and so we can implement forward and backward chaining.
- forward: proceed from knowns, add conclusions to KB, repeat
- but can do a lot of extra work if we want a specific conclusion tested
- backward: recursive, i.e. prove(C) means (prove(A) and prove(B)).
- like all recursion stuff, can do smart, i.e. stack of sub-goals without repeats