How to convert First-Order Logic into Conjunctive Normal Form (CNF) and use Resolution graphs to prove theorems.
To perform automated theorem proving, AI systems convert logical sentences into a standardized format called Conjunctive Normal Form (CNF). A sentence in CNF is a conjunction (∧) of clauses, where each clause is a disjunction (∨) of literals (a literal is a predicate or its negation).
Converting complex logical sentences into normal forms (like CNF or DNF) provides several major advantages for AI reasoning systems:
- Common Language: Acts as a unified standard for logic-based AI systems, enabling consistent knowledge representation and exchange.
- Simplifies Reasoning: Standardized structural formats allow inference algorithms to operate systematically without needing custom logic for arbitrary sentence structures.
- Automated Theorem Proving: Advanced reasoning algorithms—most notably Resolution—require statements to be in CNF to function correctly and efficiently.
- Knowledge Base Management: Facts and rules in a Knowledge Base (KB) are easier to store, query, index, and update when maintained in a consistent normal form.
- Algorithm Compatibility & SAT Solvers: Specialized solvers (such as modern SAT and SMT solvers) operate directly on CNF clauses to perform satisfiability checking and inference efficiently.
- Universality: Every sentence in First-Order Logic can be converted into an inferentially equivalent CNF formula without losing logical meaning.
Every First-Order Logic (FOL) sentence can be converted to CNF using a systematic six-step procedure.
We illustrate the procedure using the sentence: "Everyone who loves all animals is loved by someone."
∀x[∀y(Animal(y)⇒Loves(x,y))⇒∃yLoves(y,x)]
Replace all implications (⇒) and biconditionals (⇔) using equivalent disjunctions:
- A⇒B≡¬A∨B
- A⇔B≡(¬A∨B)∧(¬B∨A)
Applying this to our example sentence:
∀x[¬∀y(¬Animal(y)∨Loves(x,y))∨∃yLoves(y,x)]
Push negation symbols (¬) inward until they apply only to individual predicates, using De Morgan's laws and quantifier negation rules:
- ¬(A∨B)≡¬A∧¬B
- ¬(A∧B)≡¬A∨¬B
- ¬∀xP(x)≡∃x¬P(x)
- ¬∃xP(x)≡∀x¬P(x)
- ¬(¬A)≡A
Pushing ¬ inward:
∀x[∃y¬(¬Animal(y)∨Loves(x,y))∨∃yLoves(y,x)]
∀x[∃y(Animal(y)∧¬Loves(x,y))∨∃yLoves(y,x)]
Ensure every quantifier uses a unique variable name to prevent scope overlaps:
∀x[∃y(Animal(y)∧¬Loves(x,y))∨(∃zQ(z))]
Renaming the second y to z:
∀x[∃y(Animal(y)∧¬Loves(x,y))∨∃zLoves(z,x)]
Skolemization eliminates existential quantifiers (∃) by replacing existential variables with Skolem constants or Skolem functions:
- Skolem Constant: Used when an existential quantifier is not enclosed within any universal quantifier scope. Replace the existential variable with a new constant symbol (e.g., ∃xRich(x)→Rich(G1)).
- Skolem Function: Used when an existential quantifier lies within the scope of a universal quantifier. The existential variable depends on the universally quantified variable, so it is replaced with a new function of that variable.
- Example 1 (Skolem Function): "For every person x, there exists a person y that x loves" (∀x∃yLoves(x,y)).
- Replacing y with Skolem function c or f(x) yields: ∀xLoves(x,f(x)). (The person loved depends on x).
- Example 2 (Mother function): ∀x∃y(Mother(x,y)∧Loves(y,x)).
- Replacing y with Skolem function mother_of(x) yields: ∀x(Mother(x,mother_of(x))∧Loves(mother_of(x),x)).
- Example 3 ("Everyone has a heart"): ∀x(Person(x)⇒∃y(Heart(y)∧Has(x,y))).
- Skolemizing y→H(x) yields: ∀x(Person(x)⇒Heart(H(x))∧Has(x,H(x))).
In our sentence:
- Existential variable y is inside universal quantifier x⟹ replace y with F(x).
- Existential variable z is inside universal quantifier x⟹ replace z with G(x).
∀x[(Animal(F(x))∧¬Loves(x,F(x)))∨Loves(G(x),x)]
Since all remaining variables are universally quantified, we drop the explicit ∀ symbols. All variables are implicitly assumed to be universally quantified:
(Animal(F(x))∧¬Loves(x,F(x)))∨Loves(G(x),x)
Use the distributive law (A∧B)∨C≡(A∨C)∧(B∨C) to yield conjunctions of disjunctions:
(Animal(F(x))∨Loves(G(x),x))∧(¬Loves(x,F(x))∨Loves(G(x),x))
This gives two final CNF clauses:
- Clause 1a: Animal(F(x))∨Loves(G(x),x)
- Clause 1b: ¬Loves(x,F(x))∨Loves(G(x),x)
Resolution is a powerful inference rule for automated theorem proving in CNF formulas.
Given two clauses containing complementary literals (e.g., A and ¬A), resolution eliminates the complementary literals and combines the remaining literals into a new clause called the resolvent:
Resolvent: B∨CClause 1: A∨BClause 2: ¬A∨C
To prove a query G from a Knowledge Base KB:
- Negate the Goal: Assume ¬G.
- Convert to FOPL: Translate all facts, rules, and ¬G into First-Order Logic.
- Convert to CNF: Standardize all sentences into CNF clauses.
- Derive Contradiction: Repeatedly apply the resolution rule to derive the empty clause (⊥). Deriving ⊥ proves that KB∧¬G is unsatisfiable, thus proving G is true.
A Resolution Graph is a Directed Acyclic Graph (DAG) that visualizes the step-by-step resolution process:
- Nodes: Represent individual clauses (either initial input clauses or derived resolvents).
- Edges: Point from parent clauses to their derived resolvent clause.
- Leaf Nodes: The original input clauses from the KB and negated goal.
- Root Node: The empty clause (⊥), indicating contradiction and completing the proof.
Given the CNF clauses:
- A∨B
- ¬A
- ¬B
- Step 1: Resolve Clause (1) A∨B and Clause (2) ¬A by eliminating A and ¬A⟹ Resolvent: B.
- Step 2: Resolve B with Clause (3) ¬B⟹ Resolvent: ⊥ (Contradiction).
Let's solve a complete resolution problem step by step:
Domain Facts:
- Everyone who loves all animals is a lover of nature.
- Jack loves all animals.
- Cats are animals.
- Jack does not love nature.
-
Statement 1: ∀x[(∀y(Animal(y)⇒Loves(x,y)))⇒LovesNature(x)]
- Implication removal: ∀x[¬(∀y(¬Animal(y)∨Loves(x,y)))∨LovesNature(x)]
- Push negation inward: ∀x[(∃y(Animal(y)∧¬Loves(x,y)))∨LovesNature(x)]
- Skolemize (y→f(x)): ∀x[(Animal(f(x))∧¬Loves(x,f(x)))∨LovesNature(x)]
- Distribute ∨ over ∧:
- Clause 1a (C1a): Animal(f(x))∨LovesNature(x)
- Clause 1b (C1b): ¬Loves(x,f(x))∨LovesNature(x)
-
Statement 2: ∀y(Animal(y)⇒Loves(Jack,y))
- Clause 2 (C2): ¬Animal(y)∨Loves(Jack,y)
-
Statement 3: Cats are animals.
- Clause 3 (C3): Animal(Cat)
-
Statement 4: Jack does not love nature.
- Clause 4 (C4): ¬LovesNature(Jack)
- Resolve C2 and C3 with substitution {y/Cat}:
- Parent 1: ¬Animal(y)∨Loves(Jack,y)
- Parent 2: Animal(Cat)
- Clause 5 (C5): Loves(Jack,Cat)
- Resolve C1b and C5 with substitution {x/Jack,f(Jack)=Cat}:
- Parent 1: ¬Loves(x,f(x))∨LovesNature(x)
- Parent 2: Loves(Jack,Cat)
- Clause 6 (C6): LovesNature(Jack)
- Resolve C6 and C4:
- Parent 1: LovesNature(Jack)
- Parent 2: ¬LovesNature(Jack)
- Clause 7 (C7): ⊥ (Contradiction!)
Let's work through the classic theorem-proving puzzle:
Facts:
- Everyone who loves all animals is loved by someone.
- Anyone who kills an animal is loved by no one.
- Jack loves all animals.
- Either Jack or Curiosity killed the cat, who is named Tuna.
- Tuna is a cat.
- Cats are animals.
Goal: Prove that Curiosity killed the cat (Kills(Curiosity,Tuna)).
¬G:¬Kills(Curiosity,Tuna)
- Statement A: ∀x[(∀yAnimal(y)⇒Loves(x,y))⇒∃yLoves(y,x)]
- Clause A1: Animal(F(x))∨Loves(G(x),x)
- Clause A2: ¬Loves(x,F(x))∨Loves(G(x),x)
- Statement B: ∀x[(∃zAnimal(z)∧Kills(x,z))⇒(∀y¬Loves(y,x))]
- Clause B: ¬Loves(y,x)∨¬Animal(z)∨¬Kills(x,z)
- Statement C: ∀x(Animal(x)⇒Loves(Jack,x))
- Clause C: ¬Animal(w)∨Loves(Jack,w)
- Statement D: Kills(Jack,Tuna)∨Kills(Curiosity,Tuna)
- Clause D: Kills(Jack,Tuna)∨Kills(Curiosity,Tuna)
- Statement E: Cat(Tuna)
- Clause E: Cat(Tuna)
- Statement F: ∀x(Cat(x)⇒Animal(x))
- Clause F: ¬Cat(u)∨Animal(u)
- Statement ¬G (Negated Goal):
- Clause G: ¬Kills(Curiosity,Tuna)
- Resolve E and F ({u/Tuna}):
- Parent 1: Cat(Tuna)
- Parent 2: ¬Cat(u)∨Animal(u)
- Resolvent R1: Animal(Tuna)
- Resolve D and G:
- Parent 1: Kills(Jack,Tuna)∨Kills(Curiosity,Tuna)
- Parent 2: ¬Kills(Curiosity,Tuna)
- Resolvent R2: Kills(Jack,Tuna)
- Resolve B and R2 ({x/Jack,z/Tuna}):
- Parent 1: ¬Loves(y,x)∨¬Animal(z)∨¬Kills(x,z)
- Parent 2: Kills(Jack,Tuna)
- Resolvent R3: ¬Loves(y,Jack)∨¬Animal(Tuna)
- Resolve R3 and R1:
- Parent 1: ¬Loves(y,Jack)∨¬Animal(Tuna)
- Parent 2: Animal(Tuna)
- Resolvent R4: ¬Loves(y,Jack)
- Resolve A2 and C ({x/Jack,w/F(Jack)}):
- Parent 1: ¬Loves(x,F(x))∨Loves(G(x),x)
- Parent 2: ¬Animal(w)∨Loves(Jack,w)
- Resolvent R5: ¬Animal(F(Jack))∨Loves(G(Jack),Jack)
- Resolve R5 and A1 ({x/Jack}):
- Parent 1: ¬Animal(F(Jack))∨Loves(G(Jack),Jack)
- Parent 2: Animal(F(x))∨Loves(G(x),x)
- Resolvent R6: Loves(G(Jack),Jack)
- Resolve R6 and R4 ({y/G(Jack)}):
- Parent 1: Loves(G(Jack),Jack)
- Parent 2: ¬Loves(y,Jack)
- Resolvent R7: ⊥ (Contradiction!)
Deriving the empty clause (⊥) confirms that the negated goal is false, proving conclusively that Curiosity killed the cat.