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.minisat;
31  
32  import org.sat4j.core.ASolverFactory;
33  import org.sat4j.minisat.constraints.MixedDataStructureDanielHT;
34  import org.sat4j.minisat.constraints.MixedDataStructureDanielWL;
35  import org.sat4j.minisat.constraints.MixedDataStructureSingleWL;
36  import org.sat4j.minisat.core.DataStructureFactory;
37  import org.sat4j.minisat.core.ICDCL;
38  import org.sat4j.minisat.core.IOrder;
39  import org.sat4j.minisat.core.SearchParams;
40  import org.sat4j.minisat.core.Solver;
41  import org.sat4j.minisat.learning.LimitedLearning;
42  import org.sat4j.minisat.learning.MiniSATLearning;
43  import org.sat4j.minisat.learning.NoLearningButHeuristics;
44  import org.sat4j.minisat.learning.PercentLengthLearning;
45  import org.sat4j.minisat.orders.PhaseCachingAutoEraseStrategy;
46  import org.sat4j.minisat.orders.RSATLastLearnedClausesPhaseSelectionStrategy;
47  import org.sat4j.minisat.orders.RSATPhaseSelectionStrategy;
48  import org.sat4j.minisat.orders.RandomWalkDecorator;
49  import org.sat4j.minisat.orders.VarOrderHeap;
50  import org.sat4j.minisat.restarts.ArminRestarts;
51  import org.sat4j.minisat.restarts.Glucose21Restarts;
52  import org.sat4j.minisat.restarts.LubyRestarts;
53  import org.sat4j.minisat.restarts.MiniSATRestarts;
54  import org.sat4j.minisat.restarts.NoRestarts;
55  import org.sat4j.opt.MinOneDecorator;
56  import org.sat4j.specs.ISolver;
57  import org.sat4j.tools.DimacsOutputSolver;
58  import org.sat4j.tools.OptToSatAdapter;
59  import org.sat4j.tools.StatisticsSolver;
60  
61  /**
62   * User friendly access to pre-constructed solvers.
63   * 
64   * @author leberre
65   */
66  public final class SolverFactory extends ASolverFactory<ISolver> {
67  
68      /**
69       * 
70       */
71      private static final long serialVersionUID = 1L;
72  
73      // thread safe implementation of the singleton design pattern
74      private static SolverFactory instance;
75  
76      /**
77       * Private constructor. Use singleton method instance() instead.
78       * 
79       * @see #instance()
80       */
81      private SolverFactory() {
82          super();
83      }
84  
85      private static synchronized void createInstance() {
86          if (instance == null) {
87              instance = new SolverFactory();
88          }
89      }
90  
91      /**
92       * Access to the single instance of the factory.
93       * 
94       * @return the singleton of that class.
95       */
96      public static SolverFactory instance() {
97          if (instance == null) {
98              createInstance();
99          }
100         return instance;
101     }
102 
103     /**
104      * @return a "default" "minilearning" solver learning clauses of size
105      *         smaller than 10 % of the total number of variables with a heap
106      *         based var order.
107      */
108     public static Solver<DataStructureFactory> newMiniLearningHeap() {
109         return newMiniLearningHeap(new MixedDataStructureDanielWL());
110     }
111 
112     public static ICDCL<DataStructureFactory> newMiniLearningHeapEZSimp() {
113         Solver<DataStructureFactory> solver = newMiniLearningHeap();
114         solver.setSimplifier(solver.SIMPLE_SIMPLIFICATION);
115         return solver;
116     }
117 
118     public static Solver<DataStructureFactory> newMiniLearningHeapExpSimp() {
119         Solver<DataStructureFactory> solver = newMiniLearningHeap();
120         solver.setSimplifier(solver.EXPENSIVE_SIMPLIFICATION);
121         return solver;
122     }
123 
124     public static Solver<DataStructureFactory> newMiniLearningHeapRsatExpSimp() {
125         Solver<DataStructureFactory> solver = newMiniLearningHeapExpSimp();
126         solver.setOrder(new VarOrderHeap(new RSATPhaseSelectionStrategy()));
127         return solver;
128     }
129 
130     public static Solver<DataStructureFactory> newMiniLearningHeapRsatExpSimpBiere() {
131         Solver<DataStructureFactory> solver = newMiniLearningHeapRsatExpSimp();
132         solver.setRestartStrategy(new ArminRestarts());
133         solver.setSearchParams(new SearchParams(1.1, 100));
134         return solver;
135     }
136 
137     public static ICDCL<DataStructureFactory> newMiniLearningHeapRsatExpSimpLuby() {
138         ICDCL<DataStructureFactory> solver = newMiniLearningHeapRsatExpSimp();
139         solver.setRestartStrategy(new LubyRestarts(512));
140         return solver;
141     }
142 
143     public static ICDCL<DataStructureFactory> newGlucose21() {
144         Solver<DataStructureFactory> solver = newMiniLearningHeapRsatExpSimp();
145         solver.setRestartStrategy(new Glucose21Restarts());
146         solver.setLearnedConstraintsDeletionStrategy(solver.glucose);
147         return solver;
148     }
149 
150     private static Solver<DataStructureFactory> newBestCurrentSolverConfiguration(
151             DataStructureFactory dsf) {
152         MiniSATLearning<DataStructureFactory> learning = new MiniSATLearning<DataStructureFactory>();
153         Solver<DataStructureFactory> solver = new Solver<DataStructureFactory>(
154                 learning, dsf, new VarOrderHeap(
155                         new RSATPhaseSelectionStrategy()), new ArminRestarts());
156         solver.setSearchParams(new SearchParams(1.1, 100));
157         solver.setSimplifier(solver.EXPENSIVE_SIMPLIFICATION);
158         return solver;
159     }
160 
161     /**
162      * 
163      * @since 2.2
164      */
165     public static ICDCL<DataStructureFactory> newGreedySolver() {
166         MiniSATLearning<DataStructureFactory> learning = new MiniSATLearning<DataStructureFactory>();
167         Solver<DataStructureFactory> solver = new Solver<DataStructureFactory>(
168                 learning, new MixedDataStructureDanielWL(),
169                 new RandomWalkDecorator(new VarOrderHeap(
170                         new RSATPhaseSelectionStrategy())), new NoRestarts());
171         // solver.setSearchParams(new SearchParams(1.1, 100));
172         solver.setSimplifier(solver.EXPENSIVE_SIMPLIFICATION);
173         return solver;
174     }
175 
176     /**
177      * @since 2.2
178      */
179     public static ICDCL<DataStructureFactory> newDefaultAutoErasePhaseSaving() {
180         ICDCL<DataStructureFactory> solver = newBestWL();
181         solver.setOrder(new VarOrderHeap(new PhaseCachingAutoEraseStrategy()));
182         return solver;
183     }
184 
185     /**
186      * @since 2.2.3
187      */
188     public static ICDCL<DataStructureFactory> newDefaultMS21PhaseSaving() {
189         ICDCL<DataStructureFactory> solver = newBestWL();
190         solver.setOrder(new VarOrderHeap(
191                 new RSATLastLearnedClausesPhaseSelectionStrategy()));
192         return solver;
193     }
194 
195     /**
196      * @since 2.1
197      */
198     public static Solver<DataStructureFactory> newBestWL() {
199         return newBestCurrentSolverConfiguration(new MixedDataStructureDanielWL());
200     }
201 
202     /**
203      * 
204      * @since 2.1
205      */
206     public static ICDCL<DataStructureFactory> newBestHT() {
207         return newBestCurrentSolverConfiguration(new MixedDataStructureDanielHT());
208     }
209 
210     /**
211      * 
212      * @since 2.2
213      */
214     public static ICDCL<DataStructureFactory> newBest17() {
215         Solver<DataStructureFactory> solver = newBestCurrentSolverConfiguration(new MixedDataStructureSingleWL());
216         solver.setSimplifier(solver.EXPENSIVE_SIMPLIFICATION_WLONLY);
217         solver.setLearnedConstraintsDeletionStrategy(solver.memory_based);
218         LimitedLearning<DataStructureFactory> learning = new PercentLengthLearning<DataStructureFactory>(
219                 10);
220         solver.setLearningStrategy(learning);
221         return solver;
222     }
223 
224     /**
225      * @since 2.1
226      */
227     public static Solver<DataStructureFactory> newGlucose() {
228         Solver<DataStructureFactory> solver = newBestWL();
229         solver.setLearnedConstraintsDeletionStrategy(solver.glucose);
230         solver.setRestartStrategy(new LubyRestarts(512));
231         return solver;
232     }
233 
234     /**
235      * @param dsf
236      *            a specific data structure factory
237      * @return a default "minilearning" solver using a specific data structure
238      *         factory, learning clauses of length smaller or equals to 10 % of
239      *         the number of variables and a heap based VSIDS heuristics
240      */
241     public static Solver<DataStructureFactory> newMiniLearningHeap(
242             DataStructureFactory dsf) {
243         return newMiniLearning(dsf, new VarOrderHeap());
244     }
245 
246     /**
247      * @param dsf
248      *            the data structure factory used to represent literals and
249      *            clauses
250      * @param order
251      *            the heuristics
252      * @return a SAT solver with learning limited to clauses of length smaller
253      *         or equal to 10 percent of the total number of variables, the dsf
254      *         data structure, the FirstUIP clause generator and order as
255      *         heuristics.
256      */
257     public static Solver<DataStructureFactory> newMiniLearning(
258             DataStructureFactory dsf, IOrder order) {
259         // LimitedLearning<DataStructureFactory> learning = new
260         // PercentLengthLearning<DataStructureFactory>(10);
261         MiniSATLearning<DataStructureFactory> learning = new MiniSATLearning<DataStructureFactory>();
262         Solver<DataStructureFactory> solver = new Solver<DataStructureFactory>(
263                 learning, dsf, order, new MiniSATRestarts());
264         return solver;
265     }
266 
267     /**
268      * @return a default MiniLearning without restarts.
269      */
270     public static ICDCL<DataStructureFactory> newMiniLearningHeapEZSimpNoRestarts() {
271         LimitedLearning<DataStructureFactory> learning = new PercentLengthLearning<DataStructureFactory>(
272                 10);
273         Solver<DataStructureFactory> solver = new Solver<DataStructureFactory>(
274                 learning, new MixedDataStructureDanielWL(), new SearchParams(
275                         Integer.MAX_VALUE), new VarOrderHeap(),
276                 new MiniSATRestarts());
277         learning.setSolver(solver);
278         solver.setSimplifier(solver.SIMPLE_SIMPLIFICATION);
279         return solver;
280     }
281 
282     /**
283      * @return a default MiniLearning with restarts beginning at 1000 conflicts.
284      */
285     public static ICDCL<DataStructureFactory> newMiniLearningHeapEZSimpLongRestarts() {
286         LimitedLearning<DataStructureFactory> learning = new PercentLengthLearning<DataStructureFactory>(
287                 10);
288         Solver<DataStructureFactory> solver = new Solver<DataStructureFactory>(
289                 learning, new MixedDataStructureDanielWL(), new SearchParams(
290                         1000), new VarOrderHeap(), new MiniSATRestarts());
291         learning.setSolver(solver);
292         solver.setSimplifier(solver.SIMPLE_SIMPLIFICATION);
293         return solver;
294     }
295 
296     /**
297      * @return a SAT solver very close to the original MiniSAT sat solver.
298      */
299     public static Solver<DataStructureFactory> newMiniSATHeap() {
300         return newMiniSATHeap(new MixedDataStructureDanielWL());
301     }
302 
303     /**
304      * @return a SAT solver very close to the original MiniSAT sat solver
305      *         including easy reason simplification.
306      */
307     public static ICDCL<DataStructureFactory> newMiniSATHeapEZSimp() {
308         Solver<DataStructureFactory> solver = newMiniSATHeap();
309         solver.setSimplifier(solver.SIMPLE_SIMPLIFICATION);
310         return solver;
311     }
312 
313     public static ICDCL<DataStructureFactory> newMiniSATHeapExpSimp() {
314         Solver<DataStructureFactory> solver = newMiniSATHeap();
315         solver.setSimplifier(solver.EXPENSIVE_SIMPLIFICATION);
316         return solver;
317     }
318 
319     public static Solver<DataStructureFactory> newMiniSATHeap(
320             DataStructureFactory dsf) {
321         MiniSATLearning<DataStructureFactory> learning = new MiniSATLearning<DataStructureFactory>();
322         Solver<DataStructureFactory> solver = new Solver<DataStructureFactory>(
323                 learning, dsf, new VarOrderHeap(), new MiniSATRestarts());
324         learning.setDataStructureFactory(solver.getDSFactory());
325         learning.setVarActivityListener(solver);
326         return solver;
327     }
328 
329     /**
330      * @return MiniSAT with VSIDS heuristics, FirstUIP clause generator for
331      *         backjumping but no learning.
332      */
333     public static ICDCL<MixedDataStructureDanielWL> newBackjumping() {
334         NoLearningButHeuristics<MixedDataStructureDanielWL> learning = new NoLearningButHeuristics<MixedDataStructureDanielWL>();
335         Solver<MixedDataStructureDanielWL> solver = new Solver<MixedDataStructureDanielWL>(
336                 learning, new MixedDataStructureDanielWL(), new VarOrderHeap(),
337                 new MiniSATRestarts());
338         learning.setVarActivityListener(solver);
339         return solver;
340     }
341 
342     /**
343      * @return a solver computing models with a minimum number of satisfied
344      *         literals.
345      */
346     public static ISolver newMinOneSolver() {
347         return new OptToSatAdapter(new MinOneDecorator(newDefault()));
348     }
349 
350     /**
351      * Default solver of the SolverFactory. This solver is meant to be used on
352      * challenging SAT benchmarks.
353      * 
354      * @return the best "general purpose" SAT solver available in the factory.
355      * @see #defaultSolver() the same method, polymorphic, to be called from an
356      *      instance of ASolverFactory.
357      */
358     public static ISolver newDefault() {
359         return newGlucose21(); // newMiniLearningHeapRsatExpSimpBiere();
360     }
361 
362     @Override
363     public ISolver defaultSolver() {
364         return newDefault();
365     }
366 
367     /**
368      * Small footprint SAT solver.
369      * 
370      * @return a SAT solver suitable for solving small/easy SAT benchmarks.
371      * @see #lightSolver() the same method, polymorphic, to be called from an
372      *      instance of ASolverFactory.
373      */
374     public static ISolver newLight() {
375         return newMiniLearningHeap();
376     }
377 
378     @Override
379     public ISolver lightSolver() {
380         return newLight();
381     }
382 
383     public static ISolver newDimacsOutput() {
384         return new DimacsOutputSolver();
385     }
386 
387     public static ISolver newStatistics() {
388         return new StatisticsSolver();
389     }
390 
391 }