001 /* 002 * Created on Dec 4, 2004 003 * 004 */ 005 package aima.test.logictest.prop.algorithms; 006 007 import java.util.List; 008 009 import junit.framework.TestCase; 010 import aima.logic.propositional.algorithms.DPLL; 011 import aima.logic.propositional.algorithms.KnowledgeBase; 012 import aima.logic.propositional.algorithms.Model; 013 import aima.logic.propositional.parsing.PEParser; 014 import aima.logic.propositional.parsing.ast.Sentence; 015 import aima.logic.propositional.parsing.ast.Symbol; 016 import aima.logic.propositional.visitors.CNFClauseGatherer; 017 import aima.logic.propositional.visitors.CNFTransformer; 018 import aima.logic.propositional.visitors.SymbolCollector; 019 import aima.util.Converter; 020 021 /** 022 * @author Ravi Mohan 023 * 024 */ 025 026 public class DPLLTest extends TestCase { 027 028 private KnowledgeBase one, two, three, four; 029 030 private DPLL dpll; 031 032 private PEParser parser; 033 034 @Override 035 public void setUp() { 036 parser = new PEParser(); 037 dpll = new DPLL(); 038 } 039 040 public void testDPLLReturnsTrueWhenAllClausesTrueInModel() { 041 Model model = new Model(); 042 model = model.extend(new Symbol("A"), true).extend(new Symbol("B"), 043 true); 044 Sentence sentence = (Sentence) parser.parse("((A AND B) AND (A OR B))"); 045 boolean satisfiable = dpll.dpllSatisfiable(sentence, model); 046 assertEquals(true, satisfiable); 047 } 048 049 public void testDPLLReturnsFalseWhenOneClauseFalseInModel() { 050 Model model = new Model(); 051 model = model.extend(new Symbol("A"), true).extend(new Symbol("B"), 052 false); 053 Sentence sentence = (Sentence) parser.parse("((A OR B) AND (A => B))"); 054 boolean satisfiable = dpll.dpllSatisfiable(sentence, model); 055 assertEquals(false, satisfiable); 056 } 057 058 public void testDPLLFiltersClausesTheStatusOfWhichAreKnown() { 059 Model model = new Model(); 060 model = model.extend(new Symbol("A"), true).extend(new Symbol("B"), 061 true); 062 Sentence sentence = (Sentence) parser 063 .parse("((A AND B) AND (B AND C))"); 064 List<Sentence> clauseList = new Converter<Sentence>() 065 .setToList(new CNFClauseGatherer() 066 .getClausesFrom(new CNFTransformer() 067 .transform(sentence))); 068 List clausesWithNonTrueValues = dpll.clausesWithNonTrueValues( 069 clauseList, model); 070 assertEquals(1, clausesWithNonTrueValues.size()); 071 Sentence nonTrueClause = (Sentence) parser.parse("(B AND C)"); 072 clausesWithNonTrueValues.contains(nonTrueClause); 073 } 074 075 public void testDPLLFilteringNonTrueClausesGivesNullWhenAllClausesAreKnown() { 076 Model model = new Model(); 077 model = model.extend(new Symbol("A"), true).extend(new Symbol("B"), 078 true).extend(new Symbol("C"), true); 079 Sentence sentence = (Sentence) parser 080 .parse("((A AND B) AND (B AND C))"); 081 List<Sentence> clauseList = new Converter<Sentence>() 082 .setToList(new CNFClauseGatherer() 083 .getClausesFrom(new CNFTransformer() 084 .transform(sentence))); 085 List clausesWithNonTrueValues = dpll.clausesWithNonTrueValues( 086 clauseList, model); 087 assertEquals(0, clausesWithNonTrueValues.size()); 088 } 089 090 public void testDPLLFindsPurePositiveSymbolsWhenTheyExist() { 091 Model model = new Model(); 092 model = model.extend(new Symbol("A"), true).extend(new Symbol("B"), 093 true); 094 Sentence sentence = (Sentence) parser 095 .parse("((A AND B) AND (B AND C))"); 096 List<Sentence> clauseList = new Converter<Sentence>() 097 .setToList(new CNFClauseGatherer() 098 .getClausesFrom(new CNFTransformer() 099 .transform(sentence))); 100 List<Symbol> symbolList = new Converter<Symbol>() 101 .setToList(new SymbolCollector().getSymbolsIn(sentence)); 102 103 DPLL.SymbolValuePair sv = dpll.findPureSymbolValuePair(clauseList, 104 model, symbolList); 105 assertNotNull(sv); 106 assertEquals(new Symbol("C"), sv.symbol); 107 assertEquals(new Boolean(true), sv.value); 108 } 109 110 public void testDPLLFindsPureNegativeSymbolsWhenTheyExist() { 111 Model model = new Model(); 112 model = model.extend(new Symbol("A"), true).extend(new Symbol("B"), 113 true); 114 Sentence sentence = (Sentence) parser 115 .parse("((A AND B) AND ( B AND (NOT C) ))"); 116 List<Sentence> clauseList = new Converter<Sentence>() 117 .setToList(new CNFClauseGatherer() 118 .getClausesFrom(new CNFTransformer() 119 .transform(sentence))); 120 List<Symbol> symbolList = new Converter<Symbol>() 121 .setToList(new SymbolCollector().getSymbolsIn(sentence)); 122 123 DPLL.SymbolValuePair sv = dpll.findPureSymbolValuePair(clauseList, 124 model, symbolList); 125 assertNotNull(sv); 126 assertEquals(new Symbol("C"), sv.symbol); 127 assertEquals(new Boolean(false), sv.value); 128 } 129 130 public void testDPLLSucceedsWithAandNotA() { 131 Sentence sentence = (Sentence) parser.parse("(A AND (NOT A))"); 132 boolean satisfiable = dpll.dpllSatisfiable(sentence); 133 assertEquals(false, satisfiable); 134 } 135 136 public void testDPLLSucceedsWithChadCarffsBugReport() { 137 KnowledgeBase kb = new KnowledgeBase(); 138 kb.tell("(B12 <=> (P11 OR (P13 OR (P22 OR P02))))"); 139 kb.tell("(B21 <=> (P20 OR (P22 OR (P31 OR P11))))"); 140 kb.tell("(B01 <=> (P00 OR (P02 OR P11)))"); 141 kb.tell("(B10 <=> (P11 OR (P20 OR P00)))"); 142 kb.tell("(NOT B21)"); 143 kb.tell("(NOT B12)"); 144 kb.tell("(B10)"); 145 kb.tell("(B01)"); 146 assertTrue(kb.askWithDpll("(P00)")); 147 assertFalse(kb.askWithDpll("(NOT P00)")); 148 149 } 150 151 public void testDPLLSucceedsWithStackOverflowBugReport1() { 152 KnowledgeBase kb = new KnowledgeBase(); 153 Sentence sentence = (Sentence) parser 154 .parse("((A OR (NOT A)) AND (A OR B))"); 155 assertTrue(dpll.dpllSatisfiable(sentence)); 156 157 } 158 159 public void testDPLLSucceedsWithChadCarffsBugReport2() { 160 KnowledgeBase kb = new KnowledgeBase(); 161 kb.tell("(B10 <=> (P11 OR (P20 OR P00)))"); 162 kb.tell("(B01 <=> (P00 OR (P02 OR P11)))"); 163 kb.tell("(B21 <=> (P20 OR (P22 OR (P31 OR P11))))"); 164 kb.tell("(B12 <=> (P11 OR (P13 OR (P22 OR P02))))"); 165 kb.tell("(NOT B21)"); 166 kb.tell("(NOT B12)"); 167 kb.tell("(B10)"); 168 kb.tell("(B01)"); 169 assertTrue(kb.askWithDpll("(P00)")); 170 assertFalse(kb.askWithDpll("(NOT P00)")); 171 172 } 173 174 }