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