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