/*******************************************************************************
* SAT4J: a SATisfiability library for Java Copyright (C) 2004-2006 Daniel Le
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU Lesser General Public License Version 2.1 or later (the
* "LGPL"), in which case the provisions of the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of the LGPL, and not to allow others to use your version of
* this file under the terms of the EPL, indicate your decision by deleting
* the provisions above and replace them with the notice and other provisions
* required by the LGPL. If you do not delete the provisions above, a recipient
* may use your version of this file under the terms of the EPL or the LGPL.
*******************************************************************************/
package org.sat4j.minisat;
import org.sat4j.core.ASolverFactory;
import org.sat4j.minisat.constraints.CardinalityDataStructure;
import org.sat4j.minisat.constraints.ClausalDataStructureCB;
import org.sat4j.minisat.constraints.ClausalDataStructureCBHT;
import org.sat4j.minisat.constraints.MixedDataStructureDaniel;
import org.sat4j.minisat.constraints.MixedDataStructureWithBinary;
import org.sat4j.minisat.constraints.MixedDataStructureWithBinaryAndTernary;
import org.sat4j.minisat.core.DataStructureFactory;
import org.sat4j.minisat.core.ILits;
import org.sat4j.minisat.core.ILits2;
import org.sat4j.minisat.core.ILits23;
import org.sat4j.minisat.core.IOrder;
import org.sat4j.minisat.core.SearchParams;
import org.sat4j.minisat.core.Solver;
import org.sat4j.minisat.learning.ActiveLearning;
import org.sat4j.minisat.learning.FixedLengthLearning;
import org.sat4j.minisat.learning.LimitedLearning;
import org.sat4j.minisat.learning.MiniSATLearning;
import org.sat4j.minisat.learning.NoLearningButHeuristics;
import org.sat4j.minisat.learning.PercentLengthLearning;
import org.sat4j.minisat.orders.JWOrder;
import org.sat4j.minisat.orders.MyOrder;
import org.sat4j.minisat.orders.PureOrder;
import org.sat4j.minisat.orders.RSATPhaseSelectionStrategy;
import org.sat4j.minisat.orders.VarOrder;
import org.sat4j.minisat.orders.VarOrderHeap;
import org.sat4j.minisat.restarts.ArminRestarts;
import org.sat4j.minisat.restarts.LubyRestarts;
import org.sat4j.minisat.restarts.MiniSATRestarts;
import org.sat4j.minisat.uip.DecisionUIP;
import org.sat4j.minisat.uip.FirstUIP;
import org.sat4j.opt.MinOneDecorator;
import org.sat4j.specs.ISolver;
import org.sat4j.tools.DimacsOutputSolver;
import org.sat4j.tools.OptToSatAdapter;
/**
* User friendly access to pre-constructed solvers.
*
* @author leberre
*/
public class SolverFactory extends ASolverFactory<ISolver> {
/**
*
*/
private static final long serialVersionUID = 1L;
// thread safe implementation of the singleton design pattern
private static SolverFactory instance;
/**
* Private constructor. Use singleton method instance() instead.
*
* @see #instance()
*/
private SolverFactory() {
super();
}
private static synchronized void createInstance() {
if (instance == null) {
instance = new SolverFactory();
}
}
/**
* Access to the single instance of the factory.
*
* @return the singleton of that class.
*/
public static SolverFactory instance() {
if (instance == null) {
createInstance();
}
return instance;
}
/**
* @return a "default" "minilearning" solver learning clauses of size
* smaller than 10 % of the total number of variables
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearning() {
return newMiniLearning(10);
}
/**
* @return a "default" "minilearning" solver learning clauses of size
* smaller than 10 % of the total number of variables with a heap
* based var order.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningHeap() {
return newMiniLearningHeap(new MixedDataStructureDaniel());
}
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningHeapEZSimp() {
Solver<ILits,DataStructureFactory<ILits>> solver = newMiniLearningHeap();
solver.setSimplifier(solver.SIMPLE_SIMPLIFICATION);
return solver;
}
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningHeapExpSimp() {
Solver<ILits,DataStructureFactory<ILits>> solver = newMiniLearningHeap();
solver.setSimplifier(solver.EXPENSIVE_SIMPLIFICATION);
return solver;
}
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningHeapRsatExpSimp() {
Solver<ILits,DataStructureFactory<ILits>> solver = newMiniLearningHeapExpSimp();
solver.setOrder(new VarOrderHeap<ILits>(new RSATPhaseSelectionStrategy()));
return solver;
}
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningHeapRsatExpSimpBiere() {
Solver<ILits,DataStructureFactory<ILits>> solver = newMiniLearningHeapRsatExpSimp();
solver.setRestartStrategy(new ArminRestarts());
solver.setSearchParams(new SearchParams(1.1, 100));
return solver;
}
public static Solver<ILits,DataStructureFactory<ILits>> newMiniSatHeapRsatExpSimpBiere() {
Solver<ILits,DataStructureFactory<ILits>> solver = newMiniSATHeapExpSimp();
solver.setOrder(new VarOrderHeap<ILits>(new RSATPhaseSelectionStrategy()));
solver.setRestartStrategy(new ArminRestarts());
solver.setSearchParams(new SearchParams(1.1, 100));
return solver;
}
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningHeapRsatExpSimpLuby() {
Solver<ILits,DataStructureFactory<ILits>> solver = newMiniLearningHeapRsatExpSimp();
solver.setRestartStrategy(new LubyRestarts());
return solver;
}
/**
* @param n
* the maximal size of the clauses to learn as a percentage
* of the initial number of variables
* @return a "minilearning" solver learning clauses of size smaller than n
* of the total number of variables
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearning(int n) {
return newMiniLearning(new MixedDataStructureDaniel(), n);
}
/**
* @param dsf
* a specific data structure factory
* @return a default "minilearning" solver using a specific data structure
* factory, learning clauses of length smaller or equals to 10 % of
* the number of variables.
*/
public static <L extends ILits> Solver<L,DataStructureFactory<L>> newMiniLearning(
DataStructureFactory<L> dsf) {
return newMiniLearning(dsf, 10);
}
/**
* @param dsf
* a specific data structure factory
* @return a default "minilearning" solver using a specific data structure
* factory, learning clauses of length smaller or equals to 10 % of
* the number of variables and a heap based VSIDS heuristics
*/
public static <L extends ILits> Solver<L,DataStructureFactory<L>> newMiniLearningHeap(
DataStructureFactory<L> dsf) {
return newMiniLearning(dsf, new VarOrderHeap<L>());
}
/**
* @return a default minilearning solver using a specific data structure
* described in Lawrence Ryan thesis to handle binary clauses.
* @see #newMiniLearning
*/
public static Solver<ILits2,DataStructureFactory<ILits2>> newMiniLearning2() {
return newMiniLearning(new MixedDataStructureWithBinary());
}
public static Solver<ILits2,DataStructureFactory<ILits2>> newMiniLearning2Heap() {
return newMiniLearningHeap(new MixedDataStructureWithBinary());
}
/**
* @return a default minilearning solver using a specific data structures
* described in Lawrence Ryan thesis to handle binary and ternary
* clauses.
* @see #newMiniLearning
*/
public static Solver<ILits23,DataStructureFactory<ILits23>> newMiniLearning23() {
return newMiniLearning(new MixedDataStructureWithBinaryAndTernary());
}
/**
* @return a default minilearning SAT solver using counter-based clause
* representation (i.e. all the literals of a clause are watched)
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningCB() {
return newMiniLearning(new ClausalDataStructureCB());
}
/**
* @return a default minilearning SAT solver using counter-based clause
* representation (i.e. all the literals of a clause are watched)
* for the ORIGINAL clauses and watched-literals clause
* representation for learnt clauses.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningCBWL() {
return newMiniLearning(new ClausalDataStructureCBHT());
}
public static Solver<ILits2,DataStructureFactory<ILits2>> newMiniLearning2NewOrder() {
return newMiniLearning(new MixedDataStructureWithBinary(),
new MyOrder());
}
/**
* @return a default minilearning SAT solver choosing periodically to branch
* on "pure watched" literals if any. (a pure watched literal l is a
* literal that is watched on at least one clause such that its
* negation is not watched at all. It is not necessarily a watched
* literal.)
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningPure() {
return newMiniLearning(new MixedDataStructureDaniel(), new PureOrder());
}
/**
* @return a default minilearning SAT solver choosing periodically to branch
* on literal "pure in the original set of clauses" if any.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningCBWLPure() {
return newMiniLearning(new ClausalDataStructureCBHT(), new PureOrder());
}
/**
* @param dsf
* the data structure factory used to represent literals and
* clauses
* @param n
* the maximum size of learnt clauses as percentage of the
* original number of variables.
* @return a SAT solver with learning limited to clauses of length smaller
* or equal to n, the dsf data structure, the FirstUIP clause
* generator and a sort of VSIDS heuristics.
*/
public static <L extends ILits> Solver<L,DataStructureFactory<L>> newMiniLearning(
DataStructureFactory<L> dsf, int n) {
LimitedLearning<L,DataStructureFactory<L>> learning = new PercentLengthLearning<L,DataStructureFactory<L>>(n);
Solver<L,DataStructureFactory<L>> solver = new Solver<L,DataStructureFactory<L>>(new FirstUIP(), learning, dsf,
new VarOrder<L>(), new MiniSATRestarts());
learning.setSolver(solver);
return solver;
}
/**
* @param dsf
* the data structure factory used to represent literals and
* clauses
* @param order
* the heuristics
* @return a SAT solver with learning limited to clauses of length smaller
* or equal to 10 percent of the total number of variables, the dsf
* data structure, the FirstUIP clause generator and order as
* heuristics.
*/
public static <L extends ILits> Solver<L,DataStructureFactory<L>> newMiniLearning(
DataStructureFactory<L> dsf, IOrder<L> order) {
LimitedLearning<L,DataStructureFactory<L>> learning = new PercentLengthLearning<L,DataStructureFactory<L>>(10);
Solver<L,DataStructureFactory<L>> solver = new Solver<L,DataStructureFactory<L>>(new FirstUIP(), learning, dsf, order,
new MiniSATRestarts());
learning.setSolver(solver);
return solver;
}
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningEZSimp() {
return newMiniLearningEZSimp(new MixedDataStructureDaniel());
}
// public static ISolver newMiniLearning2EZSimp() {
// return newMiniLearningEZSimp(new MixedDataStructureWithBinary());
// }
public static <L extends ILits> Solver<L,DataStructureFactory<L>> newMiniLearningEZSimp(
DataStructureFactory<L> dsf) {
LimitedLearning<L,DataStructureFactory<L>> learning = new PercentLengthLearning<L,DataStructureFactory<L>>(10);
Solver<L,DataStructureFactory<L>> solver = new Solver<L,DataStructureFactory<L>>(new FirstUIP(), learning, dsf,
new VarOrder<L>(), new MiniSATRestarts());
learning.setSolver(solver);
solver.setSimplifier(solver.SIMPLE_SIMPLIFICATION);
return solver;
}
/**
* @return a default MiniLearning without restarts.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningHeapEZSimpNoRestarts() {
LimitedLearning<ILits,DataStructureFactory<ILits>> learning = new PercentLengthLearning<ILits,DataStructureFactory<ILits>>(10);
Solver<ILits,DataStructureFactory<ILits>> solver = new Solver<ILits,DataStructureFactory<ILits>>(new FirstUIP(), learning,
new MixedDataStructureDaniel(), new SearchParams(
Integer.MAX_VALUE), new VarOrderHeap<ILits>(),
new MiniSATRestarts());
learning.setSolver(solver);
solver.setSimplifier(solver.SIMPLE_SIMPLIFICATION);
return solver;
}
/**
* @return a default MiniLearning with restarts beginning at 1000 conflicts.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniLearningHeapEZSimpLongRestarts() {
LimitedLearning<ILits,DataStructureFactory<ILits>> learning = new PercentLengthLearning<ILits,DataStructureFactory<ILits>>(10);
Solver<ILits,DataStructureFactory<ILits>> solver = new Solver<ILits,DataStructureFactory<ILits>>(new FirstUIP(), learning,
new MixedDataStructureDaniel(), new SearchParams(1000),
new VarOrderHeap<ILits>(), new MiniSATRestarts());
learning.setSolver(solver);
solver.setSimplifier(solver.SIMPLE_SIMPLIFICATION);
return solver;
}
/**
* @return a SAT solver using First UIP clause generator, watched literals,
* VSIDS like heuristics learning only clauses having a great number
* of active variables, i.e. variables with an activity strictly
* greater than one.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newActiveLearning() {
ActiveLearning<ILits,DataStructureFactory<ILits>> learning = new ActiveLearning<ILits,DataStructureFactory<ILits>>();
Solver<ILits,DataStructureFactory<ILits>> s = new Solver<ILits,DataStructureFactory<ILits>>(new FirstUIP(), learning,
new MixedDataStructureDaniel(), new VarOrder<ILits>(),
new MiniSATRestarts());
learning.setOrder(s.getOrder());
learning.setSolver(s);
return s;
}
/**
* @return a SAT solver very close to the original MiniSAT sat solver.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniSAT() {
return newMiniSAT(new MixedDataStructureDaniel());
}
/**
* @return MiniSAT without restarts.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniSATNoRestarts() {
MiniSATLearning<ILits,DataStructureFactory<ILits>> learning = new MiniSATLearning<ILits,DataStructureFactory<ILits>>();
Solver<ILits,DataStructureFactory<ILits>> solver = new Solver<ILits,DataStructureFactory<ILits>>(new FirstUIP(), learning,
new MixedDataStructureDaniel(), new SearchParams(
Integer.MAX_VALUE), new VarOrder<ILits>(),
new MiniSATRestarts());
learning.setDataStructureFactory(solver.getDSFactory());
learning.setVarActivityListener(solver);
return solver;
}
/**
* @return MiniSAT with a special data structure from Lawrence Ryan thesis
* for managing binary clauses.
*/
public static Solver<ILits2,DataStructureFactory<ILits2>> newMiniSAT2() {
return newMiniSAT(new MixedDataStructureWithBinary());
}
/**
* @return MiniSAT with a special data structure from Lawrence Ryan thesis
* for managing binary and ternary clauses.
*/
public static Solver<ILits23,DataStructureFactory<ILits23>> newMiniSAT23() {
return newMiniSAT(new MixedDataStructureWithBinaryAndTernary());
}
/**
* @param dsf
* the data structure used for representing clauses and lits
* @return MiniSAT the data structure dsf.
*/
public static <L extends ILits> Solver<L,DataStructureFactory<L>> newMiniSAT(
DataStructureFactory<L> dsf) {
MiniSATLearning<L,DataStructureFactory<L>> learning = new MiniSATLearning<L,DataStructureFactory<L>>();
Solver<L,DataStructureFactory<L>> solver = new Solver<L,DataStructureFactory<L>>(new FirstUIP(), learning, dsf,
new VarOrder<L>(), new MiniSATRestarts());
learning.setDataStructureFactory(solver.getDSFactory());
learning.setVarActivityListener(solver);
return solver;
}
/**
* @return a SAT solver very close to the original MiniSAT sat solver.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniSATHeap() {
return newMiniSATHeap(new MixedDataStructureDaniel());
}
/**
* @return a SAT solver very close to the original MiniSAT sat solver
* including easy reason simplification.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniSATHeapEZSimp() {
Solver<ILits,DataStructureFactory<ILits>> solver = newMiniSATHeap();
solver.setSimplifier(solver.SIMPLE_SIMPLIFICATION);
return solver;
}
public static Solver<ILits,DataStructureFactory<ILits>> newMiniSATHeapExpSimp() {
Solver<ILits,DataStructureFactory<ILits>> solver = newMiniSATHeap();
solver.setSimplifier(solver.EXPENSIVE_SIMPLIFICATION);
return solver;
}
/**
* @return MiniSAT with a special data structure from Lawrence Ryan thesis
* for managing binary clauses.
*/
public static Solver<ILits2,DataStructureFactory<ILits2>> newMiniSAT2Heap() {
return newMiniSATHeap(new MixedDataStructureWithBinary());
}
/**
* @return MiniSAT with a special data structure from Lawrence Ryan thesis
* for managing binary and ternary clauses.
*/
public static Solver<ILits23,DataStructureFactory<ILits23>> newMiniSAT23Heap() {
return newMiniSATHeap(new MixedDataStructureWithBinaryAndTernary());
}
public static <L extends ILits> Solver<L,DataStructureFactory<L>> newMiniSATHeap(
DataStructureFactory<L> dsf) {
MiniSATLearning<L,DataStructureFactory<L>> learning = new MiniSATLearning<L,DataStructureFactory<L>>();
Solver<L,DataStructureFactory<L>> solver = new Solver<L,DataStructureFactory<L>>(new FirstUIP(), learning, dsf,
new VarOrderHeap<L>(), new MiniSATRestarts());
learning.setDataStructureFactory(solver.getDSFactory());
learning.setVarActivityListener(solver);
return solver;
}
/**
* @return MiniSAT with data structures to handle cardinality constraints.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newMiniCard() {
return newMiniSAT(new CardinalityDataStructure());
}
/**
* @return MiniSAT with decision UIP clause generator.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newRelsat() {
MiniSATLearning<ILits,DataStructureFactory<ILits>> learning = new MiniSATLearning<ILits,DataStructureFactory<ILits>>();
Solver<ILits,DataStructureFactory<ILits>> solver = new Solver<ILits,DataStructureFactory<ILits>>(new DecisionUIP(), learning,
new MixedDataStructureDaniel(), new VarOrderHeap<ILits>(),
new MiniSATRestarts());
learning.setDataStructureFactory(solver.getDSFactory());
learning.setVarActivityListener(solver);
return solver;
}
/**
* @return MiniSAT with VSIDS heuristics, FirstUIP clause generator for
* backjumping but no learning.
*/
public static Solver<ILits,DataStructureFactory<ILits>> newBackjumping() {
NoLearningButHeuristics<ILits,DataStructureFactory<ILits>> learning = new NoLearningButHeuristics<ILits,DataStructureFactory<ILits>>();
Solver<ILits,DataStructureFactory<ILits>> solver = new Solver<ILits,DataStructureFactory<ILits>>(new FirstUIP(), learning,
new MixedDataStructureDaniel(), new VarOrderHeap<ILits>(),
new MiniSATRestarts());
learning.setVarActivityListener(solver);
return solver;
}
/**
* @return a SAT solver with learning limited to clauses of length smaller
* or equals to 3, with a specific data structure for binary and
* ternary clauses as found in Lawrence Ryan thesis, without
* restarts, with a Jeroslow/Wang kind of heuristics.
*/
public static Solver<ILits23,DataStructureFactory<ILits23>> newMini3SAT() {
LimitedLearning<ILits23,DataStructureFactory<ILits23>> learning = new FixedLengthLearning<ILits23,DataStructureFactory<ILits23>>(3);
Solver<ILits23,DataStructureFactory<ILits23>> solver = new Solver<ILits23,DataStructureFactory<ILits23>>(new FirstUIP(), learning,
new MixedDataStructureWithBinaryAndTernary(), new SearchParams(
Integer.MAX_VALUE), new JWOrder(),
new MiniSATRestarts());
learning.setSolver(solver);
return solver;
}
/**
* @return a Mini3SAT with full learning.
* @see #newMini3SAT()
*/
public static Solver<ILits23,DataStructureFactory<ILits23>> newMini3SATb() {
MiniSATLearning<ILits23,DataStructureFactory<ILits23>> learning = new MiniSATLearning<ILits23,DataStructureFactory<ILits23>>();
Solver<ILits23,DataStructureFactory<ILits23>> solver = new Solver<ILits23,DataStructureFactory<ILits23>>(new FirstUIP(), learning,
new MixedDataStructureWithBinaryAndTernary(), new SearchParams(
Integer.MAX_VALUE), new JWOrder(),
new MiniSATRestarts());
learning.setDataStructureFactory(solver.getDSFactory());
learning.setVarActivityListener(solver);
return solver;
}
/**
* @return a solver computing models with a minimum number of satisfied literals.
*/
public static ISolver newMinOneSolver() {
return new OptToSatAdapter(new MinOneDecorator(newDefault()));
}
/**
* Default solver of the SolverFactory. This solver is meant to be used on
* challenging SAT benchmarks.
*
* @return the best "general purpose" SAT solver available in the factory.
* @see #defaultSolver() the same method, polymorphic, to be called from an
* instance of ASolverFactory.
*/
public static ISolver newDefault() {
return newMiniLearningHeapRsatExpSimpBiere();
}
@Override
public ISolver defaultSolver() {
return newDefault();
}
/**
* Small footprint SAT solver.
*
* @return a SAT solver suitable for solving small/easy SAT benchmarks.
* @see #lightSolver() the same method, polymorphic, to be called from an
* instance of ASolverFactory.
*/
public static ISolver newLight() {
return newMini3SAT();
}
@Override
public ISolver lightSolver() {
return newLight();
}
public static ISolver newDimacsOutput() {
return new DimacsOutputSolver();
}
}