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 pseudo boolean algorithms described in:
20  * A fast pseudo-Boolean constraint solver Chai, D.; Kuehlmann, A.
21  * Computer-Aided Design of Integrated Circuits and Systems, IEEE Transactions on
22  * Volume 24, Issue 3, March 2005 Page(s): 305 - 317
23  * 
24  * and 
25  * Heidi E. Dixon, 2004. Automating Pseudo-Boolean Inference within a DPLL 
26  * Framework. Ph.D. Dissertation, University of Oregon.
27  *******************************************************************************/
28  package org.sat4j.pb;
29  
30  import org.sat4j.core.ASolverFactory;
31  import org.sat4j.minisat.core.ILits;
32  import org.sat4j.minisat.core.IOrder;
33  import org.sat4j.minisat.core.IPhaseSelectionStrategy;
34  import org.sat4j.minisat.learning.ClauseOnlyLearning;
35  import org.sat4j.minisat.learning.MiniSATLearning;
36  import org.sat4j.minisat.learning.NoLearningButHeuristics;
37  import org.sat4j.minisat.orders.PhaseInLastLearnedClauseSelectionStrategy;
38  import org.sat4j.minisat.orders.RSATPhaseSelectionStrategy;
39  import org.sat4j.minisat.orders.UserFixedPhaseSelectionStrategy;
40  import org.sat4j.minisat.orders.VarOrderHeap;
41  import org.sat4j.minisat.restarts.MiniSATRestarts;
42  import org.sat4j.minisat.uip.FirstUIP;
43  import org.sat4j.pb.constraints.CompetPBMaxClauseCardConstrDataStructure;
44  import org.sat4j.pb.constraints.PBMaxCBClauseCardConstrDataStructure;
45  import org.sat4j.pb.constraints.PBMaxClauseAtLeastConstrDataStructure;
46  import org.sat4j.pb.constraints.PBMaxClauseCardConstrDataStructure;
47  import org.sat4j.pb.constraints.PBMaxDataStructure;
48  import org.sat4j.pb.constraints.PBMinClauseCardConstrDataStructure;
49  import org.sat4j.pb.constraints.PBMinDataStructure;
50  import org.sat4j.pb.constraints.PuebloPBMinClauseAtLeastConstrDataStructure;
51  import org.sat4j.pb.constraints.PuebloPBMinClauseCardConstrDataStructure;
52  import org.sat4j.pb.constraints.PuebloPBMinDataStructure;
53  import org.sat4j.pb.core.PBDataStructureFactory;
54  import org.sat4j.pb.core.PBSolverCP;
55  import org.sat4j.pb.core.PBSolverClause;
56  import org.sat4j.pb.core.PBSolverResolution;
57  import org.sat4j.pb.core.PBSolverWithImpliedClause;
58  import org.sat4j.pb.orders.VarOrderHeapObjective;
59  import org.sat4j.specs.ISolver;
60  import org.sat4j.tools.DimacsOutputSolver;
61  
62  /**
63   * User friendly access to pre-constructed solvers.
64   * 
65   * @author leberre
66   */
67  public class SolverFactory extends ASolverFactory<IPBSolver> {
68  
69      /**
70       * 
71       */
72      private static final long serialVersionUID = 1L;
73  
74      // thread safe implementation of the singleton design pattern
75      private static SolverFactory instance;
76  
77      /**
78       * Private contructor. Use singleton method instance() instead.
79       * 
80       * @see #instance()
81       */
82      private SolverFactory() {
83  
84      }
85  
86      private static synchronized void createInstance() {
87          if (instance == null) {
88              instance = new SolverFactory();
89          }
90      }
91  
92      /**
93       * Access to the single instance of the factory.
94       * 
95       * @return the singleton of that class.
96       */
97      public static SolverFactory instance() {
98          if (instance == null) {
99              createInstance();
100         }
101         return instance;
102     }
103 
104     /**
105      * @return MiniSAT with Counter-based pseudo boolean constraints and clause
106      *         learning.
107      */
108     public static PBSolverResolution newPBResAllPB() {
109         return newPBRes(new PBMaxDataStructure());
110     }
111 
112     /**
113      * @return MiniSAT with Counter-based pseudo boolean constraints and
114      *         constraint learning.
115      */
116     public static PBSolverCP<ILits> newPBCPAllPB() {
117         return newPBCP(new PBMaxDataStructure());
118     }
119 
120 
121     /**
122      * @return Solver used to display in a string the pb-instance in OPB format.
123      */
124     public static IPBSolver newOPBStringSolver() {
125         return new OPBStringSolver();
126     }
127 
128     /**
129      * @return MiniSAT with Counter-based pseudo boolean constraints and
130      *         constraint learning. Clauses and cardinalities with watched
131      *         literals are also handled (and learnt).
132      */
133     public static PBSolverCP<ILits> newPBCPMixedConstraints() {
134         return newPBCP(new PBMaxClauseCardConstrDataStructure());
135     }
136 
137     public static PBSolverCP<ILits> newCompetPBCPMixedConstraints() {
138         return newPBCP(new CompetPBMaxClauseCardConstrDataStructure());
139     }
140 
141     /**
142      * @return MiniSAT with Counter-based pseudo boolean constraints and
143      *         constraint learning. Clauses and cardinalities with watched
144      *         literals are also handled (and learnt). A specific heuristics
145      *         taking into account the objective value is used.
146      */
147     public static PBSolverCP<ILits> newPBCPMixedConstraintsObjective() {
148         return newPBCP(new CompetPBMaxClauseCardConstrDataStructure(),
149                 new VarOrderHeapObjective());
150     }
151 
152     public static PBSolverCP<ILits> newCompetPBCPMixedConstraintsObjective() {
153         return newPBCP(new CompetPBMaxClauseCardConstrDataStructure(),
154                 new VarOrderHeapObjective());
155     }
156 
157     /**
158      * @return MiniLearning with Counter-based pseudo boolean constraints and
159      *         constraint learning. Clauses and cardinalities with watched
160      *         literals are also handled (and learnt). A specific heuristics
161      *         taking into account the objective value is used. Conflict
162      *         analysis with full cutting plane inference. Only clauses are
163      *         recorded.
164      */
165     public static PBSolverCP<ILits> newPBCPMixedConstraintsObjectiveLearnJustClauses() {
166         ClauseOnlyLearning<ILits, PBDataStructureFactory<ILits>> learning = new ClauseOnlyLearning<ILits, PBDataStructureFactory<ILits>>();
167         PBSolverCP<ILits> solver = new PBSolverCP<ILits>(new FirstUIP(),
168                 learning, new PBMaxClauseCardConstrDataStructure(),
169                 new VarOrderHeapObjective());
170         learning.setSolver(solver);
171         return solver;
172     }
173 
174     public static PBSolverCP<ILits> newCompetPBCPMixedConstraintsObjectiveLearnJustClauses() {
175         ClauseOnlyLearning<ILits, PBDataStructureFactory<ILits>> learning = new ClauseOnlyLearning<ILits, PBDataStructureFactory<ILits>>();
176         PBSolverCP<ILits> solver = new PBSolverCP<ILits>(new FirstUIP(),
177                 learning, new CompetPBMaxClauseCardConstrDataStructure(),
178                 new VarOrderHeapObjective());
179         learning.setSolver(solver);
180         return solver;
181     }
182 
183     private static PBSolverCP<ILits> newPBKiller(IPhaseSelectionStrategy phase) {
184         ClauseOnlyLearning<ILits, PBDataStructureFactory<ILits>> learning = new ClauseOnlyLearning<ILits, PBDataStructureFactory<ILits>>();
185         PBSolverCP<ILits> solver = new PBSolverCP<ILits>(new FirstUIP(),
186                 learning, new PBMaxClauseCardConstrDataStructure(),
187                 new VarOrderHeapObjective(phase));
188         learning.setSolver(solver);
189         return solver;
190     }
191 
192     public static PBSolverCP<ILits> newPBKillerRSAT() {
193         return newPBKiller(new RSATPhaseSelectionStrategy());
194     }
195 
196     public static PBSolverCP<ILits> newPBKillerClassic() {
197         return newPBKiller(new PhaseInLastLearnedClauseSelectionStrategy());
198     }
199 
200     public static PBSolverCP<ILits> newPBKillerFixed() {
201         return newPBKiller(new UserFixedPhaseSelectionStrategy());
202     }
203 
204     private static PBSolverCP<ILits> newCompetPBKiller(IPhaseSelectionStrategy phase) {
205         ClauseOnlyLearning<ILits, PBDataStructureFactory<ILits>> learning = new ClauseOnlyLearning<ILits, PBDataStructureFactory<ILits>>();
206         PBSolverCP<ILits> solver = new PBSolverCP<ILits>(new FirstUIP(),
207                 learning, new CompetPBMaxClauseCardConstrDataStructure(),
208                 new VarOrderHeapObjective(phase));
209         learning.setSolver(solver);
210         return solver;
211     }
212 
213     public static PBSolverCP<ILits> newCompetPBKillerRSAT() {
214         return newCompetPBKiller(new RSATPhaseSelectionStrategy());
215     }
216 
217     public static PBSolverCP<ILits> newCompetPBKillerClassic() {
218         return newCompetPBKiller(new PhaseInLastLearnedClauseSelectionStrategy());
219     }
220 
221     public static PBSolverCP<ILits> newCompetPBKillerFixed() {
222         return newCompetPBKiller(new UserFixedPhaseSelectionStrategy());
223     }
224 
225     /**
226      * @return MiniLearning with Counter-based pseudo boolean constraints and
227      *         constraint learning. Clauses and cardinalities with watched
228      *         literals are also handled (and learnt). A specific heuristics
229      *         taking into account the objective value is used. Conflict
230      *         analysis reduces to clauses to avoid computations
231      */
232     public static PBSolverCP<ILits> newMiniLearningOPBClauseCardConstrMaxSpecificOrderIncrementalReductionToClause() {
233         // LimitedLearning learning = new LimitedLearning(10);
234         MiniSATLearning<ILits, PBDataStructureFactory<ILits>> learning = new MiniSATLearning<ILits, PBDataStructureFactory<ILits>>();
235         // LearningStrategy learning = new NoLearningButHeuristics();
236         PBSolverCP<ILits> solver = new PBSolverClause(new FirstUIP(), learning,
237                 new PBMaxClauseCardConstrDataStructure(),
238                 new VarOrderHeapObjective());
239         learning.setDataStructureFactory(solver.getDSFactory());
240         learning.setVarActivityListener(solver);
241         return solver;
242     }
243 
244     public static PBSolverCP<ILits> newCompetMiniLearningOPBClauseCardConstrMaxSpecificOrderIncrementalReductionToClause() {
245         // LimitedLearning learning = new LimitedLearning(10);
246         MiniSATLearning<ILits, PBDataStructureFactory<ILits>> learning = new MiniSATLearning<ILits, PBDataStructureFactory<ILits>>();
247         // LearningStrategy learning = new NoLearningButHeuristics();
248         PBSolverCP<ILits> solver = new PBSolverClause(new FirstUIP(), learning,
249                 new CompetPBMaxClauseCardConstrDataStructure(),
250                 new VarOrderHeapObjective());
251         learning.setDataStructureFactory(solver.getDSFactory());
252         learning.setVarActivityListener(solver);
253         return solver;
254     }
255 
256     /**
257      * @return MiniLearning with Counter-based pseudo boolean constraints and
258      *         constraint learning. Clauses and cardinalities with watched
259      *         literals are also handled (and learnt). A specific heuristics
260      *         taking into account the objective value is used. The PB
261      *         constraints are not learnt (watched), just used for backjumping.
262      */
263     public static PBSolverCP<ILits> newPBCPMixedConstraintsObjectiveNoLearning() {
264         NoLearningButHeuristics<ILits, PBDataStructureFactory<ILits>> learning = new NoLearningButHeuristics<ILits, PBDataStructureFactory<ILits>>();
265         // SearchParams params = new SearchParams(1.1,100);
266         PBSolverCP<ILits> solver = new PBSolverCP<ILits>(new FirstUIP(),
267                 learning, new PBMaxClauseCardConstrDataStructure(),
268                 new VarOrderHeapObjective());
269         learning.setSolver(solver);
270         learning.setVarActivityListener(solver);
271         return solver;
272     }
273 
274     public static PBSolverCP<ILits> newCompetPBCPMixedConstraintsObjectiveNoLearning() {
275         NoLearningButHeuristics<ILits, PBDataStructureFactory<ILits>> learning = new NoLearningButHeuristics<ILits, PBDataStructureFactory<ILits>>();
276         // SearchParams params = new SearchParams(1.1,100);
277         PBSolverCP<ILits> solver = new PBSolverCP<ILits>(new FirstUIP(),
278                 learning, new CompetPBMaxClauseCardConstrDataStructure(),
279                 new VarOrderHeapObjective());
280         learning.setSolver(solver);
281         learning.setVarActivityListener(solver);
282         return solver;
283     }
284 
285     public static PBSolverResolution newPBResMixedConstraintsObjective() {
286         MiniSATLearning<ILits, PBDataStructureFactory<ILits>> learning = new MiniSATLearning<ILits, PBDataStructureFactory<ILits>>();
287         PBSolverResolution solver = new PBSolverResolution(new FirstUIP(),
288                 learning, new PBMaxClauseCardConstrDataStructure(),
289                 new VarOrderHeapObjective(), new MiniSATRestarts());
290         learning.setDataStructureFactory(solver.getDSFactory());
291         learning.setVarActivityListener(solver);
292         return solver;
293     }
294 
295     public static PBSolverResolution newCompetPBResMixedConstraintsObjective() {
296         MiniSATLearning<ILits, PBDataStructureFactory<ILits>> learning = new MiniSATLearning<ILits, PBDataStructureFactory<ILits>>();
297         PBSolverResolution solver = new PBSolverResolution(new FirstUIP(),
298                 learning, new CompetPBMaxClauseCardConstrDataStructure(),
299                 new VarOrderHeapObjective(), new MiniSATRestarts());
300         learning.setDataStructureFactory(solver.getDSFactory());
301         learning.setVarActivityListener(solver);
302         return solver;
303     }
304 
305     public static PBSolverResolution newCompetPBResMixedConstraintsObjectiveExpSimp() {
306     	PBSolverResolution solver = newCompetPBResMixedConstraintsObjective();
307     	solver.setSimplifier(solver.EXPENSIVE_SIMPLIFICATION);
308     	return solver;
309     }
310     
311     /**
312      * @return MiniSAT with Counter-based pseudo boolean constraints and
313      *         constraint learning. Clauses and cardinalities with watched
314      *         literals are also handled (and learnt). A reduction of
315      *         PB-constraints to clauses is made in order to simplify cutting
316      *         planes.
317      */
318     public static PBSolverClause newPBCPMixedConstraintsReduceToClause() {
319         MiniSATLearning<ILits, PBDataStructureFactory<ILits>> learning = new MiniSATLearning<ILits, PBDataStructureFactory<ILits>>();
320         PBSolverClause solver = new PBSolverClause(new FirstUIP(), learning,
321                 new PBMaxClauseCardConstrDataStructure(),
322                 new VarOrderHeap<ILits>());
323         learning.setDataStructureFactory(solver.getDSFactory());
324         learning.setVarActivityListener(solver);
325         return solver;
326     }
327 
328     public static PBSolverClause newCompetPBCPMixedConstraintsReduceToClause() {
329         MiniSATLearning<ILits, PBDataStructureFactory<ILits>> learning = new MiniSATLearning<ILits, PBDataStructureFactory<ILits>>();
330         PBSolverClause solver = new PBSolverClause(new FirstUIP(), learning,
331                 new CompetPBMaxClauseCardConstrDataStructure(),
332                 new VarOrderHeap<ILits>());
333         learning.setDataStructureFactory(solver.getDSFactory());
334         learning.setVarActivityListener(solver);
335         return solver;
336     }
337 
338     /**
339      * @return MiniSAT with Counter-based pseudo boolean constraints and
340      *         constraint learning. Clauses and cardinalities with watched
341      *         literals are also handled (and learnt). a pre-processing is
342      *         applied which adds implied clauses from PB-constraints.
343      */
344     public static PBSolverWithImpliedClause newPBCPMixedConstrainsImplied() {
345         MiniSATLearning<ILits, PBDataStructureFactory<ILits>> learning = new MiniSATLearning<ILits, PBDataStructureFactory<ILits>>();
346         PBSolverWithImpliedClause solver = new PBSolverWithImpliedClause(
347                 new FirstUIP(), learning,
348                 new PBMaxClauseCardConstrDataStructure(),
349                 new VarOrderHeap<ILits>());
350         learning.setDataStructureFactory(solver.getDSFactory());
351         learning.setVarActivityListener(solver);
352         return solver;
353     }
354 
355     public static PBSolverWithImpliedClause newCompetPBCPMixedConstrainsImplied() {
356         MiniSATLearning<ILits, PBDataStructureFactory<ILits>> learning = new MiniSATLearning<ILits, PBDataStructureFactory<ILits>>();
357         PBSolverWithImpliedClause solver = new PBSolverWithImpliedClause(
358                 new FirstUIP(), learning,
359                 new CompetPBMaxClauseCardConstrDataStructure(),
360                 new VarOrderHeap<ILits>());
361         learning.setDataStructureFactory(solver.getDSFactory());
362         learning.setVarActivityListener(solver);
363         return solver;
364     }
365 
366     /**
367      * @return MiniSAT with Counter-based pseudo boolean constraints,
368      *         counter-based cardinalities, watched clauses and constraint
369      *         learning. methods isAssertive() and getBacktrackLevel() are
370      *         totally incremental. Conflicts for PB-constraints use a Map
371      *         structure
372      */
373     public static PBSolverCP<ILits> newMiniOPBClauseAtLeastConstrMax() {
374         return newPBCP(new PBMaxClauseAtLeastConstrDataStructure());
375     }
376 
377     /**
378      * @return MiniSAT with Counter-based pseudo boolean constraints and
379      *         clauses, watched cardinalities, and constraint learning.
380      */
381     public static PBSolverCP<ILits> newMiniOPBCounterBasedClauseCardConstrMax() {
382         return newPBCP(new PBMaxCBClauseCardConstrDataStructure());
383     }
384 
385     /**
386      * @return MiniSAT with WL-based pseudo boolean constraints and clause
387      *         learning.
388      */
389     public static PBSolverResolution newPBResAllPBWL() {
390         return newPBRes(new PBMinDataStructure());
391     }
392 
393     /**
394      * @return MiniSAT with WL-based pseudo boolean constraints and constraint
395      *         learning.
396      */
397     public static PBSolverCP<ILits> newPBCPAllPBWL() {
398         return newPBCP(new PBMinDataStructure());
399     }
400 
401     /**
402      * @return MiniSAT with WL-based pseudo boolean constraints and clause
403      *         learning.
404      */
405     public static PBSolverResolution newPBResAllPBWLPueblo() {
406         return newPBRes(new PuebloPBMinDataStructure());
407     }
408 
409     private static PBSolverResolution newPBRes(PBDataStructureFactory<ILits> dsf) {
410         MiniSATLearning<ILits, PBDataStructureFactory<ILits>> learning = new MiniSATLearning<ILits, PBDataStructureFactory<ILits>>();
411         PBSolverResolution solver = new PBSolverResolution(new FirstUIP(),
412                 learning, dsf, new VarOrderHeap<ILits>(), new MiniSATRestarts());
413         learning.setDataStructureFactory(solver.getDSFactory());
414         learning.setVarActivityListener(solver);
415         return solver;
416     }
417 
418     /**
419      * @return MiniSAT with WL-based pseudo boolean constraints and constraint
420      *         learning.
421      */
422     public static PBSolverCP<ILits> newPBCPAllPBWLPueblo() {
423         return newPBCP(new PuebloPBMinDataStructure());
424     }
425 
426     /**
427      * @return MiniSAT with WL-based pseudo boolean constraints and clauses,
428      *         cardinalities, and constraint learning.
429      */
430     public static PBSolverCP<ILits> newMiniOPBClauseCardMinPueblo() {
431         return newPBCP(new PuebloPBMinClauseCardConstrDataStructure());
432     }
433 
434     /**
435      * @return MiniSAT with WL-based pseudo boolean constraints and clauses,
436      *         cardinalities, and constraint learning.
437      */
438     public static PBSolverCP<ILits> newMiniOPBClauseCardMin() {
439         return newPBCP(new PBMinClauseCardConstrDataStructure());
440     }
441 
442     /**
443      * @return MiniSAT with WL-based pseudo boolean constraints and clauses,
444      *         counter-based cardinalities, and constraint learning.
445      */
446     public static PBSolverCP<ILits> newMiniOPBClauseAtLeastMinPueblo() {
447         return newPBCP(new PuebloPBMinClauseAtLeastConstrDataStructure());
448     }
449 
450     private static PBSolverCP<ILits> newPBCP(PBDataStructureFactory<ILits> dsf,
451             IOrder<ILits> order) {
452         MiniSATLearning<ILits, PBDataStructureFactory<ILits>> learning = new MiniSATLearning<ILits, PBDataStructureFactory<ILits>>();
453         PBSolverCP<ILits> solver = new PBSolverCP<ILits>(new FirstUIP(),
454                 learning, dsf, order);
455         learning.setDataStructureFactory(solver.getDSFactory());
456         learning.setVarActivityListener(solver);
457         return solver;
458     }
459 
460     private static PBSolverCP<ILits> newPBCP(PBDataStructureFactory<ILits> dsf) {
461         return newPBCP(dsf, new VarOrderHeap<ILits>());
462     }
463 
464     /**
465      * Default solver of the SolverFactory. This solver is meant to be used on
466      * challenging SAT benchmarks.
467      * 
468      * @return the best "general purpose" SAT solver available in the factory.
469      * @see #defaultSolver() the same method, polymorphic, to be called from an
470      *      instance of ASolverFactory.
471      */
472     public static IPBSolver newDefault() {
473         return newCompetPBCPMixedConstraintsObjective();
474         //return newCompetPBKillerClassic();
475     }
476 
477     @Override
478     public IPBSolver defaultSolver() {
479         return newDefault();
480     }
481 
482     /**
483      * Small footprint SAT solver.
484      * 
485      * @return a SAT solver suitable for solving small/easy SAT benchmarks.
486      * @see #lightSolver() the same method, polymorphic, to be called from an
487      *      instance of ASolverFactory.
488      */
489     public static IPBSolver newLight() {
490         return newCompetPBResMixedConstraintsObjectiveExpSimp();
491     }
492 
493     @Override
494     public IPBSolver lightSolver() {
495         return newLight();
496     }
497 
498     public static ISolver newDimacsOutput() {
499         return new DimacsOutputSolver();
500     }
501     
502     public static IPBSolver newEclipseP2() {
503         PBSolverResolution solver = newCompetPBResMixedConstraintsObjective();
504         solver.setTimeoutOnConflicts(300);
505         return new OptToPBSATAdapter(new PseudoOptDecorator(solver));
506     }
507 
508 }