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 lit;
182         for (IteratorInt iterator = literals.iterator(); iterator.hasNext();) {
183             lit = iterator.next();
184             if (lit > 0) {
185                 out.append("+1 x" + lit + " ");
186             } else {
187                 out.append("+1 ~x" + -lit + " ");
188             }
189         }
190         out.append(">= 1 ;\n");
191         return FAKE_CONSTR;
192     }
193 
194     /*
195      * (non-Javadoc)
196      * 
197      * @see org.sat4j.pb.IPBSolver#getExplanation()
198      */
199     public String getExplanation() {
200         // TODO Auto-generated method stub
201         return null;
202     }
203 
204     /*
205      * (non-Javadoc)
206      * 
207      * @see
208      * org.sat4j.pb.IPBSolver#setListOfVariablesForExplanation(org.sat4j.specs
209      * .IVecInt)
210      */
211     public void setListOfVariablesForExplanation(IVecInt listOfVariables) {
212         // TODO Auto-generated method stub
213 
214     }
215 
216     @Override
217     public String toString() {
218         StringBuffer out = getOut();
219         if (!this.inserted) {
220             StringBuffer tmp = new StringBuffer();
221             tmp.append("* #variable= ");
222             tmp.append(nVars());
223             tmp.append(" #constraint= ");
224             tmp.append(this.nbOfConstraints);
225             if (this.obj != null) {
226                 tmp.append("\n");
227                 tmp.append("min: ");
228                 tmp.append(this.obj);
229                 tmp.append(";");
230             }
231             out.insert(this.indxConstrObj, tmp.toString());
232             this.inserted = true;
233         }
234         return out.toString();
235     }
236 
237     @Override
238     public String toString(String prefix) {
239         return "OPB output solver";
240     }
241 
242     @Override
243     public int newVar(int howmany) {
244         StringBuffer out = getOut();
245         setNbVars(howmany);
246         // to add later the number of constraints
247         this.indxConstrObj = out.length();
248         out.append("\n");
249         return howmany;
250     }
251 
252     @Override
253     public void setExpectedNumberOfClauses(int nb) {
254     }
255 
256     public ObjectiveFunction getObjectiveFunction() {
257         return this.obj;
258     }
259 
260     @Override
261     public int nConstraints() {
262         return this.nbOfConstraints;
263     }
264 
265     public IConstr addAtMost(IVecInt literals, IVecInt coeffs, int degree)
266             throws ContradictionException {
267         StringBuffer out = getOut();
268         assert literals.size() == coeffs.size();
269         this.nbOfConstraints++;
270         for (int i = 0; i < literals.size(); i++) {
271             out.append(-coeffs.get(i));
272             out.append(" x");
273             out.append(literals.get(i));
274             out.append(" ");
275         }
276         out.append(">= ");
277         out.append(-degree);
278         out.append(" ;\n");
279         return FAKE_CONSTR;
280     }
281 
282     public IConstr addAtMost(IVecInt literals, IVec<BigInteger> coeffs,
283             BigInteger degree) throws ContradictionException {
284         StringBuffer out = getOut();
285         assert literals.size() == coeffs.size();
286         this.nbOfConstraints++;
287         for (int i = 0; i < literals.size(); i++) {
288             out.append(coeffs.get(i).negate());
289             out.append(" x");
290             out.append(literals.get(i));
291             out.append(" ");
292         }
293         out.append(">= ");
294         out.append(degree.negate());
295         out.append(" ;\n");
296         return FAKE_CONSTR;
297     }
298 
299     public IConstr addAtLeast(IVecInt literals, IVecInt coeffs, int degree)
300             throws ContradictionException {
301         StringBuffer out = getOut();
302         assert literals.size() == coeffs.size();
303         this.nbOfConstraints++;
304         for (int i = 0; i < literals.size(); i++) {
305             out.append(coeffs.get(i));
306             out.append(" x");
307             out.append(literals.get(i));
308             out.append(" ");
309         }
310         out.append(">= ");
311         out.append(degree);
312         out.append(" ;\n");
313         return FAKE_CONSTR;
314     }
315 
316     public IConstr addAtLeast(IVecInt literals, IVec<BigInteger> coeffs,
317             BigInteger degree) throws ContradictionException {
318         StringBuffer out = getOut();
319         assert literals.size() == coeffs.size();
320         this.nbOfConstraints++;
321         for (int i = 0; i < literals.size(); i++) {
322             out.append(coeffs.get(i));
323             out.append(" x");
324             out.append(literals.get(i));
325             out.append(" ");
326         }
327         out.append(">= ");
328         out.append(degree);
329         out.append(" ;\n");
330         return FAKE_CONSTR;
331 
332     }
333 
334     public IConstr addExactly(IVecInt literals, IVecInt coeffs, int weight)
335             throws ContradictionException {
336         StringBuffer out = getOut();
337         assert literals.size() == coeffs.size();
338         this.nbOfConstraints++;
339         for (int i = 0; i < literals.size(); i++) {
340             out.append(coeffs.get(i));
341             out.append(" x");
342             out.append(literals.get(i));
343             out.append(" ");
344         }
345         out.append("= ");
346         out.append(weight);
347         out.append(" ;\n");
348         return FAKE_CONSTR;
349     }
350 
351     public IConstr addExactly(IVecInt literals, IVec<BigInteger> coeffs,
352             BigInteger weight) throws ContradictionException {
353         StringBuffer out = getOut();
354         assert literals.size() == coeffs.size();
355         this.nbOfConstraints++;
356         for (int i = 0; i < literals.size(); i++) {
357             out.append(coeffs.get(i));
358             out.append(" x");
359             out.append(literals.get(i));
360             out.append(" ");
361         }
362         out.append("= ");
363         out.append(weight);
364         out.append(" ;\n");
365         return FAKE_CONSTR;
366     }
367 
368 }