/* * Kodkod -- Copyright (c) 2005-2011, Emina Torlak * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package kodkod.engine.satlab; import org.sat4j.minisat.SolverFactory; /** * A factory for generating SATSolver instances of a given type. * Built-in support is provided for <a href="http://www.sat4j.org/">SAT4J solvers</a>, * the <a href="http://www.princeton.edu/~chaff/zchaff.html">zchaff</a> solver from Princeton, * and the <a href="http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/">MiniSat</a> solver by * Niklas Eén and Niklas Sörensson. * @author Emina Torlak */ public abstract class SATFactory { /** * Constructs a new instance of SATFactory. */ protected SATFactory() {} /** * The factory that produces instances of the default sat4j solver. * @see org.sat4j.core.ASolverFactory#defaultSolver() */ public static final SATFactory DefaultSAT4J = new SATFactory() { public SATSolver instance() { return new SAT4J(SolverFactory.instance().defaultSolver()); } public String toString() { return "DefaultSAT4J"; } }; /** * The factory that produces instances of the "light" sat4j solver. The * light solver is suitable for solving many small instances of SAT problems. * @see org.sat4j.core.ASolverFactory#lightSolver() */ public static final SATFactory LightSAT4J = new SATFactory() { public SATSolver instance() { return new SAT4J(SolverFactory.instance().lightSolver()); } public String toString() { return "LightSAT4J"; } }; /** * The factory that produces instances of the zchaff solver from Princeton; * the returned instances * support only basic sat solver operations (adding variables/clauses, * solving, and obtaining a satisfying solution, if any). ZChaff is not incremental. */ public static final SATFactory ZChaff = new SATFactory() { public SATSolver instance() { return new ZChaff(); } public boolean incremental() { return false; } public String toString() { return "ZChaff"; } }; /** * The factory the produces {@link SATMinSolver cost-minimizing} * instances of the zchaff solver from Princeton. Note that cost minimization * can incur a time and/or memory overhead during solving, * so if you do not need this functionality, use the {@link #ZChaff} factory * instead. ZChaffMincost is not incremental. */ public static final SATFactory ZChaffMincost = new SATFactory() { public SATSolver instance() { return new ZChaffMincost(); } @Override public boolean minimizer() { return true; } public boolean incremental() { return false; } public String toString() { return "ZChaffMincost"; } }; /** * The factory the produces {@link SATProver proof logging} * instances of the MiniSat solver. Note that core * extraction can incur a significant time overhead during solving, * so if you do not need this functionality, use the {@link #MiniSat} factory * instead. */ public static final SATFactory MiniSatProver = new SATFactory() { public SATSolver instance() { return new MiniSatProver(); } @Override public boolean prover() { return true; } public String toString() { return "MiniSatProver"; } }; /** * The factory that produces instances of Niklas Eén and Niklas Sörensson's * MiniSat solver. */ public static final SATFactory MiniSat = new SATFactory() { public SATSolver instance() { return new MiniSat(); } public String toString() { return "MiniSat"; } }; public static final SATFactory MiniSatExternal = new SATFactory() { public SATSolver instance() { return new MiniSatExternal(); } public String toString() { return "MiniSatExternal"; } }; /** * Returns a SATFactory that produces instances of the specified * SAT4J solver. For the list of available SAT4J solvers see * {@link org.sat4j.core.ASolverFactory#solverNames() org.sat4j.core.ASolverFactory#solverNames()}. * @requires solverName is a valid solver name * @return a SATFactory that returns the instances of the specified * SAT4J solver * @see org.sat4j.core.ASolverFactory#solverNames() */ public static final SATFactory sat4jFactory(final String solverName) { return new SATFactory() { @Override public SATSolver instance() { return new SAT4J(SolverFactory.instance().createSolverByName(solverName)); } public String toString() { return solverName; } }; } /** * Returns a SATFactory that produces SATSolver wrappers for the external * SAT solver specified by the executable parameter. The solver's input * and output formats must conform to the SAT competition standards * (http://www.satcompetition.org/2004/format-solvers2004.html). The solver * will be called with the specified options, and the given tempInput file name will * be used to store the generated CNF files. If the tempOutput string is empty, * the solver specified by the executable string is assumed to write its output * to standard out; otherwise, the * solver is assumed to write its output to the tempOutput file. It is the caller's responsibility to * delete the temporary file(s) when no longer needed. External solvers are never incremental. * @return SATFactory that produces interruptible SATSolver wrappers for the specified external * SAT solver */ public static final SATFactory externalFactory(final String executable, final String tempInput, final String tempOutput, final String... options) { return new SATFactory() { @Override public SATSolver instance() { return new ExternalSolver(executable, tempInput, tempOutput, options); } @Override public boolean incremental() { return false; } }; } /** * Returns an instance of a SATSolver produced by this factory. * @return a SATSolver instance */ public abstract SATSolver instance(); /** * Returns true if the solvers returned by this.instance() are * {@link SATProver SATProvers}. Otherwise returns false. * @return true if the solvers returned by this.instance() are * {@link SATProver SATProvers}. Otherwise returns false. */ public boolean prover() { return false; } /** * Returns true if the solvers returned by this.instance() are * {@link SATMinSolver SATMinSolvers}. Otherwise returns false. * @return true if the solvers returned by this.instance() are * {@link SATMinSolver SATMinSolvers}. Otherwise returns false. */ public boolean minimizer() { return false; } /** * Returns true if the solvers returned by this.instance() are incremental; * i.e. if clauses/variables can be added to the solver between multiple * calls to solve(). * @return true if the solvers returned by this.instance() are incremental */ public boolean incremental() { return true; } }