View Javadoc

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