proj3

advertisement
CMSC671 Artificial Intelligence
Project3 Report
Zhongli Ding x6082
In this project, I implement both parts of the project using Common Lisp.
 Identification, Unification and Resolution
 Methods Summary
In this part, we do resolution on a given pair of clauses, this includes three steps: first our
program should identify a pair of opposite literals P(arg-list-1) and ~P(arg-list-2), then it
should unify the argument lists of these two opposite literals, finally, it generate the resolvent
of the two clauses over these pair of opposite literals.
1. Literal Identification
In “Definition.lisp”, I give definitions of some basic concepts. At first, I define three sets:
“CONST”(constants), “VAR”(variables), and “FUNCSYM”(function symbols). And then I
define following functions:
isConst(x): If an element x is a member of “CONST”, then it is a constant
isVar(x): If an element x is a member of “VAR”, then it is a variable
isFuncSym(x): If an element x is a member of “FUNCSYM”, then it is a function symbol
isLiteral(x): An element x is a literal if it is a list and its first element is not a list, not a
constant, not a variable, and not a function symbol
o isFunction(x): An element x is a function if it is a list and its first element is not a list and a
function symbol
o
o
o
o
In “Identification.lisp”, given two clauses, I define some functions to identify all pairs of
opposite literals from the two clauses:
o isPair(l1,l2): Two literals l1 and l2 are a pair of opposite literals if: either the (car l1) is
“not” and the (caadr l1) is equal to (car l2), or vice versa.
o inPairset(x,L): If L stands for the list of opposite pairs found, judge whether literal x is in L
o identifyPairs(clause1,clause2): For a given pair of clauses, identify each pair of opposite
literals using “dolist” loop and the above two functions
2. Unification
In “Unification.lisp”, I define all the functions used to implement the Unification Algorithm:
o
o
o
o
getArgList(x): Get the argument list of a literal or a function x
occurs(x,y): Test whether a variable x appears anywhere in function y
replaceItem(item1, item2, L): Replace all occurrences of "item1" with "item2" in the list "L"
subst-theta(theta, L): Apply a 'mgu' theta to a list 'L'
o unify(argList1,argList2) & unify-mgu(argList1,argList2, theta): Unify two argument lists
"argList1" and "argList2", return the 'mgu' theta if the two lists are unifiable, return 'NIL' if
unifiable but without any bindings, otherwise return 'Faliure' with specific reason
o unify-var(x, y): x is a variable, if y is a function and x appears anywhere in y then return
'failure', otherwise return 'x/y' in lisp notation '((x y))’
Unification Algorithm
procedure unify(p, q)
return unify-mgu(p, q, empty)
end{unify}
procedure unify-mgu(p, q, theta)
/* p and q are two lists of terms and |p| = |q| */
if p = empty then return theta; /* success */
let r = first(p) and s = first(q);
if r = s then return unify-mgu(rest(p), rest(q), theta);
if r is a variable then temp = unify-var(r, s);
else if s is a variable then temp = unify-var(s, r);
else if both r and s are functions of the same function name then
temp = unify-mgu(arglist(r), arglist(s), empty);
else return “failure”;
if temp = “failure” then return “failure”; /* p and q are not unifiable */
else { theta = subst-theta(temp, theta)  temp;
/* apply temp to old theta and then insert it into theta */
return unify(subst-theta(temp,rest(p)), subst-theta(temp,rest(q)), theta);
}
end{unify-mgu}
procedure unify-var(x, y)
if y is a function and x appears anywhere in y then return “failure”;
else return (x/y) in “((x y))”
end{unify-var}
3. Resolution
In “Resolution.lisp”, I define the functions to resolve two clauses 'clause1' and 'clause2' if
they are resolvable:
o removeElement(x, L): Remove every occurrence of an element x from a list L
o resolve (clause1,clause2): Resolve two clauses 'clause1' and 'clause2' if they are
resolvable and return the resolvent, return "NIL" if completely resolved to a null clause,
otherwise return 'Failure' with specific reason. The basic idea is to identify all opposite
pairs of the two clauses, then unify every such pair, finally get a resolvent.
 Results Summary
“Input1.lisp”: The input file for this part of the project
Following is a very simple summary of the output:
Parent Clauses
1. ((p x) (q (f x))),((not (p a)) (r y))
2. ((p a) (not (q x))),((not (p b)) (q (f b)))
3. ((not (p a)) (q (f x))),((p (f y)) (not (q (g y))))
4. ((q x a b) (p (f x a) (g x b))),((not (p y (g y b))) (r y))
5. ((p x (g x) (h b))),((not (p (f u a) v u)))
6. ((poor x) (not (smart x)) (happy x)),((not (happy z)) (exicting z))
7. ((poor x) (not (smart x)) (happy x)),((not (read y)) (smart y))
8. ((not (read y)) (smart y)),((not (happy z)) (exicting z))
Resolution Results
((Q (F A)) (R Y))
((P A) (NOT (P B)))
Failure: No unifiable opposite literal pairs!
Failure: No unifiable opposite literal pairs!
The resolvent is a null clause!
((POOR Z) (NOT (SMART Z)) (EXICTING Z))
((POOR Y) (HAPPY Y) (NOT (READ Y)))
Failure: No opposite literal pairs!
Please see the attached result file for details about opposite pairs, “mgu” etc. information
 Resolution Refutation Proof Procedure
 Methods Summary
A general ”resolution refutation proof procedure”:
procedure proof(KB, Q)
/* KB is a set of consistent, true FOL sentences, Q is a goal sentence.
It returns success(‘yes’) if KB |-- Q, and failure(‘no’) otherwise */
KB = clause(union(KB, {~Q})) /* convert KB and ~Q to clause form */
while null clause is not in KB do
pick 2 sentences, S1 and S2, in KB that contain a pair of opposite
literals whose argument lists are unifiable
/* may using different strategy */
if none can be found then return "failure"
resolvent = resolve(S1, S2)
KB = union(KB, {resolvent})
return "success "
end{resolution}
In this part, we extend the above program to a resolution refutation proof procedure using the
following “pick up” (depth-first) strategy:
0) Set the axiom set, get the negation of the theorem we want to prove
1) At step 1: The first of the parent clauses is the negation of the theorem, the other parent
clause is the first axiom in the axiom set that can be resolved with the first parent clause
2) At step I: The first of the parent clauses is the resolvent got from step I-1, the second is
the first axiom in the axiom set that can be resolved with the first parent clause
3) Return "yes" if a null clause is derived, "no" if no more resolution can be performed but a
null clause has not been derived
In “Proof.lisp”, I define two functions: proof(axioms,theorem) and proof-depth-first(axioms,
resolvent) to implement above procedure.
 Results Summary
“Input2.lisp”: The input file for this part of the project
Convert axiom into clause form manually using LISP notation:
Axioms
A1: Ancestor(x1,y1)<=Parent(x1,y1)
A2: Ancestor(x2,y2)<=Ancestor(x2,z2),Parent(z2,y2)
A3: Relative(x3,y3)<=Ancestor(z3,x3),Ancestor(z3,y3)
A4: Parent(Ed,Fred)
A5: Parent(Eve,Ed)
A6: Parent(Eve Linda)
A7: Parent(Adam,Ed)
Clauses in LISP notation
((not (Parent x1 y1)) (Ancestor x1 y1))
((not (Ancestor x2 z2)) (not (Parent z2 y2)) (Ancestor x2 y2))
((not (Ancestor z3 x3)) (not (Ancestor z3 y3)) (Relative x3 y3))
(Parent Ed Fred)
(Parent Eve Ed)
(Parent Eve Linda)
(Parent Adam Ed)
Using the program, I try to prove the following three theorems:
Theorems
1. Relative(Ed, Linda) : (Relative Ed Linda)
2. Ancestor(Adam, Fred): (Ancestor Adam Fred)
3. Ancestor(Eve, Fred) : (Ancestor Eve Fred)
Results
"Proof result:"
"YES!"
"Proof result:"
"NO!"
"Proof result:"
"NO!"
We can see that though theorem2 and theorem3 are theorems of the above axioms, but we
can’t derive them by the above proof strategy.
For details of the output (resolvents, parent clauses, ‘mgu’s etc), please see the attached
result file.
Any questions, please contact zding1@cs.umbc.edu
Download