package aima.test.core.unit.logic.propositional.inference; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Set; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import aima.core.logic.propositional.inference.DPLL; import aima.core.logic.propositional.inference.DPLLSatisfiable; import aima.core.logic.propositional.inference.OptimizedDPLL; import aima.core.logic.propositional.kb.KnowledgeBase; import aima.core.logic.propositional.kb.data.Clause; import aima.core.logic.propositional.kb.data.Model; import aima.core.logic.propositional.parsing.PLParser; import aima.core.logic.propositional.parsing.ast.PropositionSymbol; import aima.core.logic.propositional.parsing.ast.Sentence; import aima.core.logic.propositional.visitors.ConvertToConjunctionOfClauses; import aima.core.logic.propositional.visitors.SymbolCollector; /** * @author Ravi Mohan * @author Ciaran O'Reilly */ @RunWith(Parameterized.class) public class DPLLTest { private DPLL dpll; private PLParser parser; @Parameters(name = "{index}: dpll={0}") public static Collection<Object[]> inferenceAlgorithmSettings() { return Arrays.asList(new Object[][] { {new DPLLSatisfiable()}, {new OptimizedDPLL()} }); } public DPLLTest(DPLL dpll) { this.dpll = dpll; this.parser = new PLParser(); } @Test public void testDPLLReturnsTrueWhenAllClausesTrueInModel() { Model model = new Model(); model = model.union(new PropositionSymbol("A"), true).union( new PropositionSymbol("B"), true); Sentence sentence = parser.parse("A & B & (A | B)"); Set<Clause> clauses = ConvertToConjunctionOfClauses.convert(sentence) .getClauses(); List<PropositionSymbol> symbols = new ArrayList<PropositionSymbol>( SymbolCollector.getSymbolsFrom(sentence)); boolean satisfiable = dpll.dpll(clauses, symbols, model); Assert.assertEquals(true, satisfiable); } @Test public void testDPLLReturnsFalseWhenOneClauseFalseInModel() { Model model = new Model(); model = model.union(new PropositionSymbol("A"), true).union( new PropositionSymbol("B"), false); Sentence sentence = parser.parse("(A | B) & (A => B)"); Set<Clause> clauses = ConvertToConjunctionOfClauses.convert(sentence) .getClauses(); List<PropositionSymbol> symbols = new ArrayList<PropositionSymbol>( SymbolCollector.getSymbolsFrom(sentence)); boolean satisfiable = dpll.dpll(clauses, symbols, model); Assert.assertEquals(false, satisfiable); } @Test public void testDPLLSucceedsWithAandNotA() { Sentence sentence = parser.parse("A & ~A"); boolean satisfiable = dpll.dpllSatisfiable(sentence); Assert.assertEquals(false, satisfiable); } @Test public void testDPLLSucceedsWithChadCarffsBugReport() { KnowledgeBase kb = new KnowledgeBase(); kb.tell("B12 <=> P11 | P13 | P22 | P02"); kb.tell("B21 <=> P20 | P22 | P31 | P11"); kb.tell("B01 <=> P00 | P02 | P11"); kb.tell("B10 <=> P11 | P20 | P00"); kb.tell("~B21"); kb.tell("~B12"); kb.tell("B10"); kb.tell("B01"); Assert.assertTrue(dpll.isEntailed(kb, parser.parse("P00"))); Assert.assertFalse(dpll.isEntailed(kb, parser.parse("~P00"))); } @Test public void testDPLLSucceedsWithStackOverflowBugReport1() { Sentence sentence = (Sentence) parser.parse("(A | ~A) & (A | B)"); Assert.assertTrue(dpll.dpllSatisfiable(sentence)); } @Test public void testDPLLSucceedsWithChadCarffsBugReport2() { KnowledgeBase kb = new KnowledgeBase(); kb.tell("B10 <=> P11 | P20 | P00"); kb.tell("B01 <=> P00 | P02 | P11"); kb.tell("B21 <=> P20 | P22 | P31 | P11"); kb.tell("B12 <=> P11 | P13 | P22 | P02"); kb.tell("~B21"); kb.tell("~B12"); kb.tell("B10"); kb.tell("B01"); Assert.assertTrue(dpll.isEntailed(kb, parser.parse("P00"))); Assert.assertFalse(dpll.isEntailed(kb, parser.parse("~P00"))); } @Test public void testIssue66() { // http://code.google.com/p/aima-java/issues/detail?id=66 Model model = new Model(); model = model.union(new PropositionSymbol("A"), false) .union(new PropositionSymbol("B"), false) .union(new PropositionSymbol("C"), true); Sentence sentence = parser.parse("((A | B) | C)"); Set<Clause> clauses = ConvertToConjunctionOfClauses.convert(sentence) .getClauses(); List<PropositionSymbol> symbols = new ArrayList<PropositionSymbol>( SymbolCollector.getSymbolsFrom(sentence)); boolean satisfiable = dpll.dpll(clauses, symbols, model); Assert.assertEquals(true, satisfiable); } @Test public void testDoesNotKnow() { KnowledgeBase kb = new KnowledgeBase(); kb.tell("A"); Assert.assertFalse(dpll.isEntailed(kb, parser.parse("B"))); Assert.assertFalse(dpll.isEntailed(kb, parser.parse("~B"))); } }