Resolution Algorithm for Quantificational Logic in 10 steps 0. Determine the set of statements that you want to test for consistency (e.g. for an argument, that set is all your premises together with the negation of the conclusion) 1. Put statements into PNF (see LPL section 11.7) 2. Skolemize 3. Put into CNF 4. Distribute universals over conjunctions 5. Drop conjunctions 6. Remove null quantifiers 7. Change variables (using the replace bound variable equivalence principle) to ensure that no two quantifiers use the same variable 8. Drop quantifiers 9. Put into clauses 10. Resolve using unification Please note that clauses are still sets of literals, but a literal is now an atomic wff or the negation thereof (i.e. a literal can contain free variables) Also, the process of unification when resolving two clauses can be stated as follows: Let t/v indicate a substitution of a term t for a variable v (so note that we can substitute a constant, a variable, or a complex term such as f(g(a),b)) Let C[t1/v1, …, tn/vn] be the clause that results from performing the substitutions t1/v1 through tn/vn on all literals that are in clause C. E.g {A(x1,x2), A(c,f(x3))}[c/x1, f(c)/x2, c/x3] = {A(c,f(c))} (so note how such substitutions can reduce the number of literals in the clause set!) Two clauses C1 and C2 can be resolved if there exist substitutions t1/v1, …, tn/vn such that C1[t1/v1, …, tn/vn] contains some literal L and C2[t1/v1, …, tn/vn] contains L’. The resolvent is the clause C1[t1/v1, …, tn/vn] C2[t1/v1, …, tn/vn] / {L, L’} (so note that any number of substitutions can take place when resolving, including 0 (i.e. not all variables need to be substituted with anything) In the algorithm, steps 3 through 8 can be simplified by not explicitly distributing the universals over conjunctions, and by immediately dropping the quantifiers instead, as long as one makes sure to at some point change variables in accordance to step 7 (which translates to making sure that no two clauses end up using the same variable (and that, in fact, is the very reason for why we want to change variables: by making sure that no two clauses use the same variable, we are keeping open any possible unifications as much as possible)). The main reason to explicitly include these steps in the algorithm is as to demonstrate the equivalence principles being used (distribution of over , null quantification, and replacing bound variables), and hence to help understand the soundness of the method as a whole. Also, some of the steps of the algorithm can be done earlier or later. In particular, variables can be changed at various stages during this process. For example, since the process of putting statements into PNF sometimes requires one to change variables already, one could decide to change variables as step 1 (i.e. before putting into PNF). That way, one doesn’t have to worry about quantifiers capturing each other’s variables during the PNF process. Then again, the disadvantage is that when skolemizing one may end up dropping variables, so having replaced those would have been a waste of time. Moreover, after the universal over conjunction distribution, more variables may need to be changed, which is why the book waits with changing variables (other than what was needed for PNF) until after the universal over conjunction distribution. Indeed, following the simplification of the previous note, some more rewriting can be avoided by waiting with replacing variables until after the quantifiers have been dropped. Thus, a bit more efficient algorithm would be: 0. Determine set of statements 1. Put statements into PNF 2. Skolemize 3. Drop quantifiers 4. Put into CNF 5. Drop conjunctions 6. Put into clauses 7. Change variables (using the replace bound variable equivalence principle) to ensure that no two quantifiers use the same variable 8. Resolve using unification And in here, steps 5, 6, and 7 can easily be done at the same time. As an example, suppose that after step 2 I have the following statement: xy (P(x) (Q(y) R(x,y))) The original algorithm would proceed as follows: Put into CNF: xy (P(x) (Q(y) R(x,y))) (by Simplification) Distribute over : xy P(x) xy (Q(y) R(x,y)) Drop ’s: xy P(x) ; xy (Q(y) R(x,y)) Remove null quantifiers: x P(x) ; xy (Q(y) R(x,y)) (by Null Quantification) Change variables: x P(x) ; zy (Q(y) R(z,y)) (by Replacing Bound Variables) Drop ’s: P(x) ; Q(y) R(z,y) Put into Clauses: {P(x)} ; {Q(y) , R(z,y)} The more efficient algorithm, however, would proceed as follows: Drop ’s: P(x) (Q(y) R(x,y)) Put into CNF: P(x) (Q(y) R(x,y)) (by Simplification) Drop ’s: P(x) ; Q(y) R(x,y) Put into clauses: {P(x)} ; {Q(y) , R(x,y)} Change variables: {P(x)} ; {Q(y) , R(z,y)} Homework: Use resolution (where you may feel free to use short-cuts as indicated above) to demonstrate the validity of the following argument: x (P(x) y (P(y) Q(x,y))) x (P(x) y((P(y) Q(x,y)) R(x,y))) x y ((P(x) P(y)) R(x,y))