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  
31  package org.sat4j;
32  
33  import static org.junit.Assert.assertEquals;
34  import static org.junit.Assert.assertFalse;
35  import static org.junit.Assert.assertTrue;
36  import static org.junit.Assert.fail;
37  
38  import java.util.Arrays;
39  
40  import org.junit.Test;
41  import org.sat4j.core.VecInt;
42  import org.sat4j.minisat.SolverFactory;
43  import org.sat4j.specs.ContradictionException;
44  import org.sat4j.specs.ISolver;
45  import org.sat4j.specs.IVecInt;
46  import org.sat4j.specs.TimeoutException;
47  import org.sat4j.tools.Minimal4CardinalityModel;
48  import org.sat4j.tools.Minimal4InclusionModel;
49  import org.sat4j.tools.ModelIterator;
50  import org.sat4j.tools.SearchEnumeratorListener;
51  import org.sat4j.tools.SolutionCounter;
52  import org.sat4j.tools.SolutionFoundListener;
53  
54  /**
55   * @author leberre
56   * 
57   *         To change the template for this generated type comment go to
58   *         Window>Preferences>Java>Code Generation>Code and Comments
59   */
60  public class ModelIteratorTest {
61  
62      @Test
63      public void testModelIterator() {
64          try {
65              ISolver solver = new ModelIterator(SolverFactory.newDefault());
66              solver.newVar(3);
67              IVecInt clause = new VecInt();
68              clause.push(1);
69              clause.push(2);
70              clause.push(3);
71              solver.addClause(clause);
72              clause.clear();
73              clause.push(-1);
74              clause.push(-2);
75              clause.push(-3);
76              solver.addClause(clause);
77              int counter = 0;
78              while (solver.isSatisfiable()) {
79                  solver.model();
80                  counter++;
81              }
82              assertEquals(6, counter);
83          } catch (ContradictionException e) {
84              fail();
85          } catch (TimeoutException e) {
86              fail();
87          }
88      }
89  
90      @Test
91      public void testInnerModelIterator() {
92          try {
93              ISolver solver = SolverFactory.newDefault();
94              SolutionFoundListener sfl = new SolutionFoundListener() {
95  
96                  public void onSolutionFound(int[] solution) {
97                      System.out.println(new VecInt(solution));
98                  }
99  
100                 public void onSolutionFound(IVecInt solution) {
101                     throw new UnsupportedOperationException(
102                             "Not implemented yet!");
103                 }
104 
105                 public void onUnsatTermination() {
106                     // do nothing
107                 }
108 
109             };
110             SearchEnumeratorListener enumerator = new SearchEnumeratorListener(
111                     sfl);
112             solver.setSearchListener(enumerator);
113             solver.newVar(3);
114             IVecInt clause = new VecInt();
115             clause.push(1);
116             clause.push(2);
117             clause.push(3);
118             solver.addClause(clause);
119             clause.clear();
120             clause.push(-1);
121             clause.push(-2);
122             clause.push(-3);
123             solver.addClause(clause);
124             assertTrue(solver.isSatisfiable());
125             assertEquals(6, enumerator.getNumberOfSolutionFound());
126         } catch (ContradictionException e) {
127             fail();
128         } catch (TimeoutException e) {
129             fail();
130         }
131     }
132 
133     @Test
134     public void testInplicantCoverIterator() {
135         try {
136             ModelIterator solver = new ModelIterator(SolverFactory.newDefault());
137             solver.newVar(3);
138             IVecInt clause = new VecInt();
139             clause.push(1);
140             clause.push(2);
141             clause.push(3);
142             solver.addClause(clause);
143             clause.clear();
144             clause.push(-1);
145             clause.push(-2);
146             clause.push(-3);
147             solver.addClause(clause);
148             while (solver.isSatisfiable()) {
149                 int[] prime = solver.primeImplicant();
150                 System.out.println(Arrays.toString(prime));
151             }
152             assertEquals(6, solver.numberOfModelsFoundSoFar());
153         } catch (ContradictionException e) {
154             fail();
155         } catch (TimeoutException e) {
156             fail();
157         }
158     }
159 
160     @Test
161     public void testModelIteratorLimit() {
162         try {
163             ISolver solver = new ModelIterator(SolverFactory.newDefault(), 3);
164             solver.newVar(3);
165             IVecInt clause = new VecInt();
166             clause.push(1);
167             clause.push(2);
168             clause.push(3);
169             solver.addClause(clause);
170             clause.clear();
171             clause.push(-1);
172             clause.push(-2);
173             clause.push(-3);
174             solver.addClause(clause);
175             int counter = 0;
176             while (solver.isSatisfiable()) {
177                 solver.model();
178                 counter++;
179             }
180             assertEquals(3, counter);
181         } catch (ContradictionException e) {
182             fail();
183         } catch (TimeoutException e) {
184             fail();
185         }
186     }
187 
188     // Is not Implemented Yet. We need a Backup/Restore solution to do so.
189     // public void testIncMinModel() {
190     // try {
191     // ISolver solver = new ModelIterator(new
192     // Minimal4InclusionModel(SolverFactory.newMiniLearning()));
193     // solver.newVar(3);
194     // VecInt clause = new VecInt();
195     // clause.push(1);
196     // clause.push(2);
197     // clause.push(3);
198     // solver.addClause(clause);
199     // clause.clear();
200     // clause.push(-1);
201     // clause.push(-2);
202     // clause.push(-3);
203     // solver.addClause(clause);
204     // int counter = 0;
205     // while (solver.isSatisfiable()) {
206     // int[] model = solver.model();
207     // counter++;
208     // }
209     // assertEquals(3, counter);
210     // } catch (ContradictionException e) {
211     // fail();
212     // } catch (TimeoutException e) {
213     // fail();
214     // }
215     // }
216     //
217     // public void testCardMinModel() {
218     // try {
219     // ISolver solver = new ModelIterator(new
220     // Minimal4CardinalityModel(SolverFactory.newMiniLearning()));
221     // solver.newVar(3);
222     // VecInt clause = new VecInt();
223     // clause.push(1);
224     // clause.push(2);
225     // clause.push(3);
226     // solver.addClause(clause);
227     // clause.clear();
228     // clause.push(-1);
229     // clause.push(-2);
230     // clause.push(-3);
231     // solver.addClause(clause);
232     // int counter = 0;
233     // while (solver.isSatisfiable()) {
234     // int[] model = solver.model();
235     // counter++;
236     // }
237     // assertEquals(3, counter);
238     // } catch (ContradictionException e) {
239     // fail();
240     // } catch (TimeoutException e) {
241     // fail();
242     // }
243     // }
244 
245     @Test
246     public void testCardModel() {
247         try {
248             ISolver solver = new Minimal4CardinalityModel(
249                     SolverFactory.newDefault());
250             solver.newVar(3);
251             IVecInt clause = new VecInt();
252             clause.push(1);
253             clause.push(-2);
254             clause.push(3);
255             solver.addClause(clause);
256             clause.clear();
257             clause.push(-1);
258             clause.push(2);
259             clause.push(-3);
260             solver.addClause(clause);
261             int counter = 0;
262             while (solver.isSatisfiable() && counter < 10) {
263                 solver.model();
264                 counter++;
265             }
266             assertEquals(10, counter);
267         } catch (ContradictionException e) {
268             fail();
269         } catch (TimeoutException e) {
270             fail();
271         }
272     }
273 
274     @Test
275     public void testIncModel() {
276         try {
277             ISolver solver = new Minimal4InclusionModel(
278                     SolverFactory.newDefault());
279             solver.newVar(3);
280             IVecInt clause = new VecInt();
281             clause.push(1);
282             clause.push(-2);
283             clause.push(3);
284             solver.addClause(clause);
285             clause.clear();
286             clause.push(-1);
287             clause.push(2);
288             clause.push(-3);
289             solver.addClause(clause);
290             int counter = 0;
291             while (solver.isSatisfiable() && counter < 10) {
292                 solver.model();
293                 counter++;
294             }
295             assertEquals(10, counter);
296         } catch (ContradictionException e) {
297             fail();
298         } catch (TimeoutException e) {
299             fail();
300         }
301     }
302 
303     @Test
304     public void testIsSatisfiableVecInt() {
305         try {
306             ISolver solver = SolverFactory.newDefault();
307             solver.newVar(3);
308             IVecInt clause = new VecInt();
309             clause.push(1);
310             clause.push(2);
311             clause.push(3);
312             solver.addClause(clause);
313             clause.clear();
314             clause.push(-1);
315             clause.push(-2);
316             clause.push(-3);
317             solver.addClause(clause);
318             assertTrue(solver.isSatisfiable());
319             IVecInt cube = new VecInt();
320             cube.push(1);
321             assertTrue(solver.isSatisfiable(cube));
322             // printModel(solver.model());
323             cube.push(2);
324             assertEquals(2, cube.size());
325             assertTrue(solver.isSatisfiable(cube));
326             // printModel(solver.model());
327             cube.push(-3);
328             assertEquals(3, cube.size());
329             assertTrue(solver.isSatisfiable(cube));
330             // printModel(solver.model());
331             cube.pop();
332             cube.push(3);
333             assertEquals(3, cube.size());
334             // System.out.println(" cube " + cube);
335             boolean sat = solver.isSatisfiable(cube);
336             // if (sat) {
337             // printModel(solver.model());
338             // }
339             assertFalse(sat);
340         } catch (ContradictionException e) {
341             fail();
342         } catch (TimeoutException e) {
343             fail();
344         }
345     }
346 
347     @Test(timeout = 6000)
348     public void testGlobalTimeoutCounter() {
349         SolutionCounter counter = new SolutionCounter(
350                 SolverFactory.newDefault());
351         IVecInt clause = new VecInt();
352         for (int i = 1; i < 100; i++) {
353             clause.push(i);
354         }
355         try {
356             counter.addClause(clause);
357             counter.setTimeout(3);
358             counter.countSolutions();
359         } catch (TimeoutException e) {
360             assertTrue(counter.lowerBound() > 0);
361         } catch (ContradictionException e) {
362             fail();
363         }
364     }
365 
366     @Test(timeout = 6000)
367     public void testGlobalTimeoutIterator() {
368         ModelIterator iterator = new ModelIterator(SolverFactory.newDefault());
369         IVecInt clause = new VecInt();
370         for (int i = 1; i < 100; i++) {
371             clause.push(i);
372         }
373         try {
374             iterator.addClause(clause);
375             iterator.setTimeout(3);
376             while (iterator.isSatisfiable()) {
377                 iterator.model();
378             }
379         } catch (TimeoutException e) {
380 
381         } catch (ContradictionException e) {
382             fail();
383         }
384     }
385 
386     @Test(timeout = 12000)
387     public void testSpecificValues() throws ContradictionException,
388             TimeoutException {
389         assertEquals(3L, count(2));
390         assertEquals(7L, count(3));
391         assertEquals(15L, count(4));
392         assertEquals(31L, count(5));
393         assertEquals(63L, count(6));
394         assertEquals(127L, count(7));
395         assertEquals(255L, count(8));
396         assertEquals(511L, count(9));
397     }
398 
399     private long count(int size) throws ContradictionException,
400             TimeoutException {
401         SolutionCounter counter = new SolutionCounter(
402                 SolverFactory.newDefault());
403         IVecInt clause = new VecInt();
404         for (int i = 1; i <= size; i++) {
405             clause.push(i);
406         }
407         counter.addClause(clause);
408         counter.setTimeout(10);
409         return counter.countSolutions();
410     }
411 }