View Javadoc

1   /*******************************************************************************
2    * SAT4J: a SATisfiability library for Java Copyright (C) 2004, 2012 Artois University and CNRS
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the Eclipse Public License v1.0
6    * which accompanies this distribution, and is available at
7    *  http://www.eclipse.org/legal/epl-v10.html
8    *
9    * Alternatively, the contents of this file may be used under the terms of
10   * either the GNU Lesser General Public License Version 2.1 or later (the
11   * "LGPL"), in which case the provisions of the LGPL are applicable instead
12   * of those above. If you wish to allow use of your version of this file only
13   * under the terms of the LGPL, and not to allow others to use your version of
14   * this file under the terms of the EPL, indicate your decision by deleting
15   * the provisions above and replace them with the notice and other provisions
16   * required by the LGPL. If you do not delete the provisions above, a recipient
17   * may use your version of this file under the terms of the EPL or the LGPL.
18   *
19   * Based on the original MiniSat specification from:
20   *
21   * An extensible SAT solver. Niklas Een and Niklas Sorensson. Proceedings of the
22   * Sixth International Conference on Theory and Applications of Satisfiability
23   * Testing, LNCS 2919, pp 502-518, 2003.
24   *
25   * See www.minisat.se for the original solver in C++.
26   *
27   * Contributors:
28   *   CRIL - initial API and implementation
29   *******************************************************************************/
30  package org.sat4j;
31  
32  import static org.junit.Assert.assertEquals;
33  import static org.junit.Assert.assertFalse;
34  import static org.junit.Assert.assertTrue;
35  
36  import java.util.Collection;
37  
38  import org.junit.Before;
39  import org.junit.Test;
40  import org.sat4j.core.VecInt;
41  import org.sat4j.specs.ContradictionException;
42  import org.sat4j.specs.IConstr;
43  import org.sat4j.specs.ISolver;
44  import org.sat4j.specs.IVecInt;
45  import org.sat4j.specs.TimeoutException;
46  import org.sat4j.tools.xplain.Xplain;
47  
48  public abstract class AbstractXplainTest<T extends ISolver> {
49  
50      protected Xplain<T> solver;
51  
52      protected abstract Xplain<T> getXplain();
53  
54      @Before
55      public void startUp() {
56          this.solver = getXplain();
57      }
58  
59      @Test
60      public void testGlobalInconsistency() throws ContradictionException,
61              TimeoutException {
62          this.solver.newVar(2);
63          IVecInt clause = new VecInt();
64          clause.push(1).push(2);
65          this.solver.addClause(clause);
66          clause.clear();
67          clause.push(1).push(-2);
68          this.solver.addClause(clause);
69          clause.clear();
70          clause.push(-1).push(2);
71          this.solver.addClause(clause);
72          clause.clear();
73          clause.push(-1).push(-2);
74          this.solver.addClause(clause);
75          clause.clear();
76          assertFalse(this.solver.isSatisfiable());
77          Collection<IConstr> explanation = this.solver.explain();
78          assertEquals(4, explanation.size());
79      }
80  
81      @Test
82      public void testGlobalInconsistencyIndex() throws ContradictionException,
83              TimeoutException {
84          this.solver.newVar(2);
85          IVecInt clause = new VecInt();
86          clause.push(1).push(2);
87          this.solver.addClause(clause);
88          clause.clear();
89          clause.push(1).push(-2);
90          this.solver.addClause(clause);
91          clause.clear();
92          clause.push(-1).push(2);
93          this.solver.addClause(clause);
94          clause.clear();
95          clause.push(-1).push(-2);
96          this.solver.addClause(clause);
97          clause.clear();
98          assertFalse(this.solver.isSatisfiable());
99          int[] explanation = this.solver.minimalExplanation();
100         assertEquals(4, explanation.length);
101         assertEquals(1, explanation[0]);
102         assertEquals(2, explanation[1]);
103         assertEquals(3, explanation[2]);
104         assertEquals(4, explanation[3]);
105 
106     }
107 
108     @Test
109     public void testAlmostGlobalInconsistency() throws ContradictionException,
110             TimeoutException {
111         this.solver.newVar(3);
112         IVecInt clause = new VecInt();
113         clause.push(1).push(2);
114         IConstr c1 = this.solver.addClause(clause);
115         clause.clear();
116         clause.push(1).push(-2);
117         IConstr c2 = this.solver.addClause(clause);
118         clause.clear();
119         clause.push(-1).push(2);
120         IConstr c3 = this.solver.addClause(clause);
121         clause.clear();
122         clause.push(-1).push(-2);
123         IConstr c4 = this.solver.addClause(clause);
124         clause.clear();
125         clause.push(1).push(3);
126         this.solver.addClause(clause);
127         clause.clear();
128         assertFalse(this.solver.isSatisfiable());
129         Collection<IConstr> explanation = this.solver.explain();
130         assertEquals(4, explanation.size());
131         assertTrue(explanation.contains(c1));
132         assertTrue(explanation.contains(c2));
133         assertTrue(explanation.contains(c3));
134         assertTrue(explanation.contains(c4));
135     }
136 
137     @Test
138     public void testAlmostGlobalInconsistencyIndex()
139             throws ContradictionException, TimeoutException {
140         this.solver.newVar(3);
141         IVecInt clause = new VecInt();
142         clause.push(1).push(2);
143         this.solver.addClause(clause);
144         clause.clear();
145         clause.push(1).push(-2);
146         this.solver.addClause(clause);
147         clause.clear();
148         clause.push(-1).push(2);
149         this.solver.addClause(clause);
150         clause.clear();
151         clause.push(-1).push(-2);
152         this.solver.addClause(clause);
153         clause.clear();
154         clause.push(1).push(3);
155         this.solver.addClause(clause);
156         clause.clear();
157         assertFalse(this.solver.isSatisfiable());
158         int[] explanation = this.solver.minimalExplanation();
159         assertEquals(4, explanation.length);
160         assertEquals(1, explanation[0]);
161         assertEquals(2, explanation[1]);
162         assertEquals(3, explanation[2]);
163         assertEquals(4, explanation[3]);
164     }
165 
166     @Test
167     public void testAlmostGlobalInconsistencyII()
168             throws ContradictionException, TimeoutException {
169         this.solver.newVar(3);
170         IVecInt clause = new VecInt();
171         clause.push(1).push(2);
172         IConstr c1 = this.solver.addClause(clause);
173         clause.clear();
174         clause.push(1).push(-2);
175         IConstr c2 = this.solver.addClause(clause);
176         clause.clear();
177         clause.push(1).push(3);
178         this.solver.addClause(clause);
179         clause.clear();
180         clause.push(-1).push(2);
181         IConstr c4 = this.solver.addClause(clause);
182         clause.clear();
183         clause.push(-1).push(-2);
184         IConstr c5 = this.solver.addClause(clause);
185         clause.clear();
186         assertFalse(this.solver.isSatisfiable());
187         Collection<IConstr> explanation = this.solver.explain();
188         assertEquals(4, explanation.size());
189         assertTrue(explanation.contains(c1));
190         assertTrue(explanation.contains(c2));
191         assertTrue(explanation.contains(c4));
192         assertTrue(explanation.contains(c5));
193     }
194 
195     @Test
196     public void testAlmostGlobalInconsistencyIIIndex()
197             throws ContradictionException, TimeoutException {
198         this.solver.newVar(3);
199         IVecInt clause = new VecInt();
200         clause.push(1).push(2);
201         this.solver.addClause(clause);
202         clause.clear();
203         clause.push(1).push(-2);
204         this.solver.addClause(clause);
205         clause.clear();
206         clause.push(1).push(3);
207         this.solver.addClause(clause);
208         clause.clear();
209         clause.push(-1).push(2);
210         this.solver.addClause(clause);
211         clause.clear();
212         clause.push(-1).push(-2);
213         this.solver.addClause(clause);
214         clause.clear();
215         assertFalse(this.solver.isSatisfiable());
216         int[] explanation = this.solver.minimalExplanation();
217         assertEquals(4, explanation.length);
218         assertEquals(1, explanation[0]);
219         assertEquals(2, explanation[1]);
220         assertEquals(4, explanation[2]);
221         assertEquals(5, explanation[3]);
222     }
223 
224     @Test
225     public void testTheCaseOfTwoMUSes() throws ContradictionException,
226             TimeoutException {
227         this.solver.newVar(4);
228         IVecInt clause = new VecInt();
229         clause.push(1).push(2);
230         IConstr c1 = this.solver.addClause(clause);
231         clause.clear();
232         clause.push(1).push(-2);
233         IConstr c2 = this.solver.addClause(clause);
234         clause.clear();
235         clause.push(-1).push(3);
236         this.solver.addClause(clause);
237         clause.clear();
238         clause.push(-1).push(-3);
239         this.solver.addClause(clause);
240         clause.clear();
241         clause.push(-1).push(4);
242         this.solver.addClause(clause);
243         clause.clear();
244         clause.push(-1).push(-4);
245         this.solver.addClause(clause);
246         clause.clear();
247         assertFalse(this.solver.isSatisfiable());
248         Collection<IConstr> explanation = this.solver.explain();
249         assertEquals(4, explanation.size());
250         assertTrue(explanation.contains(c1));
251         assertTrue(explanation.contains(c2));
252     }
253 
254     @Test
255     public void testEclipseTestCase() throws ContradictionException,
256             TimeoutException {
257         this.solver.newVar(3);
258         IVecInt clause = new VecInt();
259         clause.push(-1);
260         this.solver.addClause(clause);
261         clause.clear();
262         clause.push(-2).push(3);
263         this.solver.addClause(clause);
264         clause.clear();
265         clause.push(-2).push(1);
266         this.solver.addClause(clause);
267         clause.clear();
268         clause.push(2);
269         this.solver.addClause(clause);
270         clause.clear();
271         assertFalse(this.solver.isSatisfiable());
272         Collection<IConstr> explanation = this.solver.explain();
273         assertEquals(3, explanation.size());
274     }
275 
276     @Test
277     public void testEclipseTestCase2() throws ContradictionException,
278             TimeoutException {
279         this.solver.newVar(4);
280         IVecInt clause = new VecInt();
281         clause.push(-1).push(2);
282         this.solver.addClause(clause);
283         clause.clear();
284         clause.push(-1).push(3);
285         this.solver.addClause(clause);
286         clause.clear();
287         clause.push(-2).push(-3);
288         this.solver.addClause(clause);
289         clause.clear();
290         clause.push(-4).push(1);
291         this.solver.addClause(clause);
292         clause.clear();
293         IVecInt assump = new VecInt();
294         assump.push(4);
295         assertFalse(this.solver.isSatisfiable(assump));
296         Collection<IConstr> explanation = this.solver.explain();
297         assertEquals(4, explanation.size());
298     }
299 }