1 /******************************************************************************* 2 * SAT4J: a SATisfiability library for Java Copyright (C) 2004-2008 Daniel Le Berre 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 *******************************************************************************/ 28 package org.sat4j.tools; 29 30 import org.sat4j.core.VecInt; 31 import org.sat4j.specs.ContradictionException; 32 import org.sat4j.specs.ISolver; 33 import org.sat4j.specs.IVecInt; 34 import org.sat4j.specs.TimeoutException; 35 36 /** 37 * That class allows to iterate through all the models (implicants) of a 38 * formula. 39 * 40 * <pre> 41 * ISolver solver = new ModelIterator(SolverFactory.OneSolver()); 42 * boolean unsat = true; 43 * while (solver.isSatisfiable()) { 44 * unsat = false; 45 * int[] model = solver.model(); 46 * // do something with model 47 * } 48 * if (unsat) { 49 * // UNSAT case 50 * } 51 * </pre> 52 * 53 * @author leberre 54 */ 55 public class ModelIterator extends SolverDecorator<ISolver> { 56 57 private static final long serialVersionUID = 1L; 58 59 private boolean trivialfalsity = false; 60 61 /** 62 * @param solver 63 */ 64 public ModelIterator(ISolver solver) { 65 super(solver); 66 } 67 68 /* 69 * (non-Javadoc) 70 * 71 * @see org.sat4j.ISolver#model() 72 */ 73 @Override 74 public int[] model() { 75 int[] last = super.model(); 76 IVecInt clause = new VecInt(last.length); 77 for (int q : last) { 78 clause.push(-q); 79 } 80 try { 81 // System.out.println("adding " + clause); 82 addClause(clause); 83 } catch (ContradictionException e) { 84 trivialfalsity = true; 85 } 86 return last; 87 } 88 89 /* 90 * (non-Javadoc) 91 * 92 * @see org.sat4j.ISolver#isSatisfiable() 93 */ 94 @Override 95 public boolean isSatisfiable() throws TimeoutException { 96 if (trivialfalsity) { 97 return false; 98 } 99 trivialfalsity = false; 100 return super.isSatisfiable(true); 101 } 102 103 /* 104 * (non-Javadoc) 105 * 106 * @see org.sat4j.ISolver#isSatisfiable(org.sat4j.datatype.VecInt) 107 */ 108 @Override 109 public boolean isSatisfiable(IVecInt assumps) throws TimeoutException { 110 if (trivialfalsity) { 111 return false; 112 } 113 trivialfalsity = false; 114 return super.isSatisfiable(assumps,true); 115 } 116 117 /* 118 * (non-Javadoc) 119 * 120 * @see org.sat4j.ISolver#reset() 121 */ 122 @Override 123 public void reset() { 124 trivialfalsity = false; 125 super.reset(); 126 } 127 }