View Javadoc

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.pb;
29  
30  import java.math.BigInteger;
31  
32  import org.sat4j.specs.ContradictionException;
33  import org.sat4j.specs.IConstr;
34  import org.sat4j.specs.IVec;
35  import org.sat4j.specs.IVecInt;
36  import org.sat4j.specs.IteratorInt;
37  import org.sat4j.specs.TimeoutException;
38  import org.sat4j.tools.DimacsStringSolver;
39  
40  /**
41   * Solver used to display in a string the pb-instance in OPB format.
42   * 
43   * That solver is useful to produce OPB files to be used by third party solvers.
44   * 
45   * @author parrain
46   * 
47   */
48  public class OPBStringSolver extends DimacsStringSolver implements IPBSolver {
49  
50  	private static final String FAKE_I_CONSTR_MSG = "Fake IConstr";
51  
52  	/**
53  	 * 
54  	 */
55  	private static final long serialVersionUID = 1L;
56  
57  	private int indxConstrObj;
58  
59  	private int nbOfConstraints;
60  
61  	private ObjectiveFunction obj;
62  
63  	private boolean inserted = false;
64  
65  	private static final IConstr FAKE_CONSTR = new IConstr() {
66  
67  		public int size() {
68  			throw new UnsupportedOperationException(FAKE_I_CONSTR_MSG);
69  		}
70  
71  		public boolean learnt() {
72  			throw new UnsupportedOperationException(FAKE_I_CONSTR_MSG);
73  		}
74  
75  		public double getActivity() {
76  			throw new UnsupportedOperationException(FAKE_I_CONSTR_MSG);
77  		}
78  
79  		public int get(int i) {
80  			throw new UnsupportedOperationException(FAKE_I_CONSTR_MSG);
81  		}
82  
83  		public boolean canBePropagatedMultipleTimes() {
84  			throw new UnsupportedOperationException(FAKE_I_CONSTR_MSG);
85  		}
86  	};
87  
88  	/**
89  	 * 
90  	 */
91  	public OPBStringSolver() {
92  	}
93  
94  	/**
95  	 * @param initSize
96  	 */
97  	public OPBStringSolver(int initSize) {
98  		super(initSize);
99  	}
100 
101 	@Override
102 	public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
103 		for (IteratorInt it = assumps.iterator(); it.hasNext();) {
104 			int p = it.next();
105 			if (p > 0) {
106 				getOut().append("+1 x" + p + " >= 1 ;\n");
107 			} else {
108 				getOut().append("-1 x" + (-p) + " >= 0 ;\n");
109 			}
110 			nbOfConstraints++;
111 		}
112 		throw new TimeoutException();
113 	}
114 
115 	@Override
116 	public boolean isSatisfiable(IVecInt assumps, boolean global)
117 			throws TimeoutException {
118 		return super.isSatisfiable(assumps, global);
119 	}
120 
121 	public IConstr addPseudoBoolean(IVecInt lits, IVec<BigInteger> coeffs,
122 			boolean moreThan, BigInteger d) throws ContradictionException {
123 		if (moreThan) {
124 			return addAtLeast(lits, coeffs, d);
125 		}
126 		return addAtMost(lits, coeffs, d);
127 	}
128 
129 	public void setObjectiveFunction(ObjectiveFunction obj) {
130 		this.obj = obj;
131 	}
132 
133 	@Override
134 	public IConstr addAtLeast(IVecInt literals, int degree)
135 			throws ContradictionException {
136 		StringBuffer out = getOut();
137 		nbOfConstraints++;
138 		int negationweight = 0;
139 		int p;
140 		for (IteratorInt iterator = literals.iterator(); iterator.hasNext();) {
141 			p = iterator.next();
142 			assert p != 0;
143 			if (p > 0) {
144 				out.append("+1 x" + p + " ");
145 			} else {
146 				out.append("-1 x" + (-p) + " ");
147 				negationweight++;
148 			}
149 		}
150 		out.append(">= " + (degree - negationweight) + " ;\n");
151 		return FAKE_CONSTR;
152 	}
153 
154 	@Override
155 	public IConstr addAtMost(IVecInt literals, int degree)
156 			throws ContradictionException {
157 		StringBuffer out = getOut();
158 		nbOfConstraints++;
159 		int negationweight = 0;
160 		int p;
161 		for (IteratorInt iterator = literals.iterator(); iterator.hasNext();) {
162 			p = iterator.next();
163 			assert p != 0;
164 			if (p > 0) {
165 				out.append("-1 x" + p + " ");
166 			} else {
167 				out.append("+1 x" + (-p) + " ");
168 				negationweight++;
169 			}
170 		}
171 		out.append(">= " + (-degree + negationweight) + " ;\n");
172 		return FAKE_CONSTR;
173 	}
174 
175 	@Override
176 	public IConstr addClause(IVecInt literals) throws ContradictionException {
177 		StringBuffer out = getOut();
178 		nbOfConstraints++;
179 		int lit;
180 		for (IteratorInt iterator = literals.iterator(); iterator.hasNext();) {
181 			lit = iterator.next();
182 			if (lit > 0) {
183 				out.append("+1 x" + lit + " ");
184 			} else {
185 				out.append("+1 ~x" + -lit + " ");
186 			}
187 		}
188 		out.append(">= 1 ;\n");
189 		return FAKE_CONSTR;
190 	}
191 
192 	/*
193 	 * (non-Javadoc)
194 	 * 
195 	 * @see org.sat4j.pb.IPBSolver#getExplanation()
196 	 */
197 	public String getExplanation() {
198 		// TODO Auto-generated method stub
199 		return null;
200 	}
201 
202 	/*
203 	 * (non-Javadoc)
204 	 * 
205 	 * @see
206 	 * org.sat4j.pb.IPBSolver#setListOfVariablesForExplanation(org.sat4j.specs
207 	 * .IVecInt)
208 	 */
209 	public void setListOfVariablesForExplanation(IVecInt listOfVariables) {
210 		// TODO Auto-generated method stub
211 
212 	}
213 
214 	@Override
215 	public String toString() {
216 		StringBuffer out = getOut();
217 		if (!inserted) {
218 			StringBuffer tmp = new StringBuffer();
219 			tmp.append("* #variable= ");
220 			tmp.append(nVars());
221 			tmp.append(" #constraint= ");
222 			tmp.append(nbOfConstraints);
223 			if (obj != null) {
224 				tmp.append("\n");
225 				tmp.append("min: ");
226 				tmp.append(obj);
227 				tmp.append(";");
228 			}
229 			out.insert(indxConstrObj, tmp.toString());
230 			inserted = true;
231 		}
232 		return out.toString();
233 	}
234 
235 	@Override
236 	public String toString(String prefix) {
237 		return "OPB output solver";
238 	}
239 
240 	@Override
241 	public int newVar(int howmany) {
242 		StringBuffer out = getOut();
243 		setNbVars(howmany);
244 		// to add later the number of constraints
245 		indxConstrObj = out.length();
246 		out.append("\n");
247 		return howmany;
248 	}
249 
250 	@Override
251 	public void setExpectedNumberOfClauses(int nb) {
252 	}
253 
254 	public ObjectiveFunction getObjectiveFunction() {
255 		return obj;
256 	}
257 
258 	@Override
259 	public int nConstraints() {
260 		return nbOfConstraints;
261 	}
262 
263 	public IConstr addAtMost(IVecInt literals, IVecInt coeffs, int degree)
264 			throws ContradictionException {
265 		StringBuffer out = getOut();
266 		assert literals.size() == coeffs.size();
267 		nbOfConstraints++;
268 		for (int i = 0; i < literals.size(); i++) {
269 			out.append(-coeffs.get(i));
270 			out.append(" x");
271 			out.append(literals.get(i));
272 			out.append(" ");
273 		}
274 		out.append(">= ");
275 		out.append(-degree);
276 		out.append(" ;\n");
277 		return FAKE_CONSTR;
278 	}
279 
280 	public IConstr addAtMost(IVecInt literals, IVec<BigInteger> coeffs,
281 			BigInteger degree) throws ContradictionException {
282 		StringBuffer out = getOut();
283 		assert literals.size() == coeffs.size();
284 		nbOfConstraints++;
285 		for (int i = 0; i < literals.size(); i++) {
286 			out.append(coeffs.get(i).negate());
287 			out.append(" x");
288 			out.append(literals.get(i));
289 			out.append(" ");
290 		}
291 		out.append(">= ");
292 		out.append(degree.negate());
293 		out.append(" ;\n");
294 		return FAKE_CONSTR;
295 	}
296 
297 	public IConstr addAtLeast(IVecInt literals, IVecInt coeffs, int degree)
298 			throws ContradictionException {
299 		StringBuffer out = getOut();
300 		assert literals.size() == coeffs.size();
301 		nbOfConstraints++;
302 		for (int i = 0; i < literals.size(); i++) {
303 			out.append(coeffs.get(i));
304 			out.append(" x");
305 			out.append(literals.get(i));
306 			out.append(" ");
307 		}
308 		out.append(">= ");
309 		out.append(degree);
310 		out.append(" ;\n");
311 		return FAKE_CONSTR;
312 	}
313 
314 	public IConstr addAtLeast(IVecInt literals, IVec<BigInteger> coeffs,
315 			BigInteger degree) throws ContradictionException {
316 		StringBuffer out = getOut();
317 		assert literals.size() == coeffs.size();
318 		nbOfConstraints++;
319 		for (int i = 0; i < literals.size(); i++) {
320 			out.append(coeffs.get(i));
321 			out.append(" x");
322 			out.append(literals.get(i));
323 			out.append(" ");
324 		}
325 		out.append(">= ");
326 		out.append(degree);
327 		out.append(" ;\n");
328 		return FAKE_CONSTR;
329 
330 	}
331 
332 	public IConstr addExactly(IVecInt literals, IVecInt coeffs, int weight)
333 			throws ContradictionException {
334 		StringBuffer out = getOut();
335 		assert literals.size() == coeffs.size();
336 		nbOfConstraints++;
337 		for (int i = 0; i < literals.size(); i++) {
338 			out.append(coeffs.get(i));
339 			out.append(" x");
340 			out.append(literals.get(i));
341 			out.append(" ");
342 		}
343 		out.append("= ");
344 		out.append(weight);
345 		out.append(" ;\n");
346 		return FAKE_CONSTR;
347 	}
348 
349 	public IConstr addExactly(IVecInt literals, IVec<BigInteger> coeffs,
350 			BigInteger weight) throws ContradictionException {
351 		StringBuffer out = getOut();
352 		assert literals.size() == coeffs.size();
353 		nbOfConstraints++;
354 		for (int i = 0; i < literals.size(); i++) {
355 			out.append(coeffs.get(i));
356 			out.append(" x");
357 			out.append(literals.get(i));
358 			out.append(" ");
359 		}
360 		out.append("= ");
361 		out.append(weight);
362 		out.append(" ;\n");
363 		return FAKE_CONSTR;
364 	}
365 
366 }