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    }