All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sat4j.sat.Lanceur Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * SAT4J: a SATisfiability library for Java Copyright (C) 2004-2008 Daniel Le Berre
 *
 * 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.sat;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Properties;
import java.util.StringTokenizer;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.sat4j.AbstractLauncher;
import org.sat4j.core.ASolverFactory;
import org.sat4j.core.VecInt;
import org.sat4j.minisat.core.DataStructureFactory;
import org.sat4j.minisat.core.IOrder;
import org.sat4j.minisat.core.IPhaseSelectionStrategy;
import org.sat4j.minisat.core.LearningStrategy;
import org.sat4j.minisat.core.RestartStrategy;
import org.sat4j.minisat.core.SearchParams;
import org.sat4j.minisat.core.Solver;
import org.sat4j.pb.IPBSolver;
import org.sat4j.pb.reader.PBInstanceReader;
import org.sat4j.reader.InstanceReader;
import org.sat4j.reader.ParseFormatException;
import org.sat4j.reader.Reader;
import org.sat4j.specs.ContradictionException;
import org.sat4j.specs.IProblem;
import org.sat4j.specs.ISolver;
import org.sat4j.specs.IVecInt;
import org.sat4j.specs.SearchListener;
import org.sat4j.tools.DotSearchTracing;

/**
 * This class is used to launch the SAT solvers from the command line. It is
 * compliant with the SAT competition (www.satcompetition.org) I/O format. The
 * launcher is to be used as follows:
 * 
 * 
 *                [solvername] filename [key=value]*
 * 
* * If no solver name is given, then the default solver of the solver factory is * used (@see org.sat4j.core.ASolverFactory#defaultSolver()). * * @author leberre */ public class Lanceur extends AbstractLauncher { /** * */ private static final long serialVersionUID = 1L; /** * Lance le prouveur sur un fichier Dimacs. * * @param args * doit contenir le nom d'un fichier Dimacs, eventuellement * compress?. */ public static void main(final String[] args) { AbstractLauncher lanceur = new Lanceur(); lanceur.run(args); System.exit(lanceur.getExitCode().value()); } protected ASolverFactory factory; private String filename; private int k = -1; @SuppressWarnings("nls") private Options createCLIOptions() { Options options = new Options(); options.addOption("l", "library", true, "specifies the name of the library used (minisat by default)"); options.addOption("s", "solver", true, "specifies the name of a prebuilt solver from the library"); options.addOption("S", "Solver", true, "setup a solver using a solver config string"); options.addOption("t", "timeout", true, "specifies the timeout (in seconds)"); options.addOption("T", "timeoutms", true, "specifies the timeout (in milliseconds)"); options.addOption("C", "conflictbased", false, "conflict based timeout (for deterministic behavior)"); options.addOption("d", "dot", true, "create a sat4j.dot file in current directory representing the search"); options.addOption("f", "filename", true, "specifies the file to use (in conjunction with -d for instance)"); options.addOption("m", "mute", false, "Set launcher in silent mode"); options.addOption("k", "kleast", true, "limit the search to models having at least k variables set to false"); options.addOption("r", "trace", true, "Search Listener to use for tracing the behavior of the solver"); Option op = options.getOption("l"); op.setArgName("libname"); op = options.getOption("s"); op.setArgName("solvername"); op = options.getOption("S"); op.setArgName("solverStringDefinition"); op = options.getOption("t"); op.setArgName("number"); op = options.getOption("T"); op.setArgName("number"); op = options.getOption("C"); op.setArgName("number"); op = options.getOption("k"); op.setArgName("number"); op = options.getOption("d"); op.setArgName("filename"); op = options.getOption("f"); op.setArgName("filename"); op = options.getOption("r"); op.setArgName("searchlistener"); return options; } /** * Configure the solver according to the command line parameters. * * @param args * the command line * @return a solver properly configured. */ @SuppressWarnings({ "nls", "unchecked" }) @Override protected ISolver configureSolver(String[] args) { Options options = createCLIOptions(); if (args.length == 0) { HelpFormatter helpf = new HelpFormatter(); helpf.printHelp("java -jar sat4j.jar", options, true); return null; } try { CommandLine cmd = new PosixParser().parse(options, args); String framework = cmd.getOptionValue("l"); //$NON-NLS-1$ if (framework == null) { //$NON-NLS-1$ framework = "minisat"; } try { Class clazz = Class .forName("org.sat4j." + framework + ".SolverFactory"); //$NON-NLS-1$ //$NON-NLS-2$ Class[] params = {}; Method m = clazz.getMethod("instance", params); //$NON-NLS-1$ factory = (ASolverFactory) m.invoke(null, (Object[]) null); } catch (Exception e) { // DLB Findbugs warning ok log("Wrong framework: " + framework + ". Using minisat instead."); factory = org.sat4j.minisat.SolverFactory.instance(); } ISolver asolver; if (cmd.hasOption("s")) { log("Available solvers: " + Arrays.asList(factory.solverNames())); String solvername = cmd.getOptionValue("s"); if (solvername == null) { asolver = factory.defaultSolver(); } else { asolver = factory.createSolverByName(solvername); } } else { asolver = factory.defaultSolver(); } if (cmd.hasOption("S")) { String configuredSolver = cmd.getOptionValue("S"); if (configuredSolver == null) { stringUsage(); return null; } asolver = configureFromString(configuredSolver, asolver); } String timeout = cmd.getOptionValue("t"); if (timeout == null) { timeout = cmd.getOptionValue("T"); if (timeout != null) { asolver.setTimeoutMs(Long.parseLong(timeout)); } } else { if (cmd.hasOption("C")) { asolver.setTimeoutOnConflicts(Integer.parseInt(timeout)); } else { asolver.setTimeout(Integer.parseInt(timeout)); } } filename = cmd.getOptionValue("f"); if (cmd.hasOption("d")) { String dotfilename = null; if (filename != null) { dotfilename = cmd.getOptionValue("d"); } if (dotfilename == null) { dotfilename = "sat4j.dot"; } asolver.setSearchListener(new DotSearchTracing(dotfilename, null)); } if (cmd.hasOption("m")) { setSilent(true); } if (cmd.hasOption("k")) { Integer myk = Integer.valueOf(cmd.getOptionValue("k")); if (myk != null) { k = myk.intValue(); } } if (cmd.hasOption("r")) { String listener = cmd.getOptionValue("r"); try { SearchListener slistener = (SearchListener) Class .forName(listener).getConstructor(String.class) .newInstance("sat4j.trace"); asolver.setSearchListener(slistener); } catch (InstantiationException e) { log("wrong parameter for search listener: " + e.getLocalizedMessage()); } catch (IllegalAccessException e) { log("wrong parameter for search listener: " + e.getLocalizedMessage()); } catch (ClassNotFoundException e) { log("wrong parameter for search listener: " + listener); } catch (IllegalArgumentException e) { log("wrong parameter for search listener: " + e.getLocalizedMessage()); } catch (SecurityException e) { log("wrong parameter for search listener: " + e.getLocalizedMessage()); } catch (InvocationTargetException e) { log("wrong parameter for search listener: " + e.getLocalizedMessage()); } catch (NoSuchMethodException e) { log("wrong parameter for search listener: " + e.getLocalizedMessage()); } } int others = 0; String[] rargs = cmd.getArgs(); if (filename == null && rargs.length > 0) { filename = rargs[others++]; } // use remaining data to configure the solver while (others < rargs.length) { String[] param = rargs[others].split("="); //$NON-NLS-1$ assert param.length == 2; log("setting " + param[0] + " to " + param[1]); //$NON-NLS-1$ //$NON-NLS-2$ try { BeanUtils.setProperty(asolver, param[0], param[1]); } catch (Exception e) { log("Cannot set parameter : " //$NON-NLS-1$ + args[others]); } others++; } getLogWriter().println(asolver.toString(COMMENT_PREFIX)); //$NON-NLS-1$ return asolver; } catch (ParseException e1) { HelpFormatter helpf = new HelpFormatter(); helpf.printHelp("java -jar sat4j.jar", options, true); usage(); } return null; } @Override protected Reader createReader(ISolver theSolver, String problemname) { if (theSolver instanceof IPBSolver) { return new PBInstanceReader((IPBSolver) theSolver); } return new InstanceReader(theSolver); } @Override public void displayLicense() { super.displayLicense(); log("This software uses some libraries from the Jakarta Commons project. See jakarta.apache.org for details."); //$NON-NLS-1$ } @Override public void usage() { showAvailableSolvers(factory); } @Override protected String getInstanceName(String[] args) { return filename; } @SuppressWarnings("unchecked") private final ISolver configureFromString(String solverconfig, ISolver theSolver) { // AFAIK, there is no easy way to solve parameterized problems // when building the solver at runtime. StringTokenizer stk = new StringTokenizer(solverconfig, ","); Properties pf = new Properties(); String token; String[] couple; while (stk.hasMoreElements()) { token = stk.nextToken(); couple = token.split("="); pf.setProperty(couple[0], couple[1]); } Solver aSolver = (Solver) theSolver; DataStructureFactory dsf = setupObject("DSF", pf); if (dsf != null) { aSolver.setDataStructureFactory(dsf); } LearningStrategy learning = setupObject("LEARNING", pf); if (learning != null) { aSolver.setLearner(learning); learning.setSolver(aSolver); } IOrder order = setupObject("ORDER", pf); if (order != null) { aSolver.setOrder(order); } IPhaseSelectionStrategy pss = setupObject("PHASE", pf); if (pss != null) { aSolver.getOrder().setPhaseSelectionStrategy(pss); } RestartStrategy restarter = setupObject("RESTARTS", pf); if (restarter != null) { aSolver.setRestartStrategy(restarter); } String simp = pf.getProperty("SIMP"); if (simp != null) { aSolver.setSimplifier(simp); } SearchParams params = setupObject("PARAMS", pf); if (params != null) { aSolver.setSearchParams(params); } String memory = pf.getProperty("MEMORY"); if ("GLUCOSE".equalsIgnoreCase(memory)) { log("configuring MEMORY"); aSolver.setLearnedConstraintsDeletionStrategy(aSolver.glucose); } return theSolver; } private void stringUsage() { log("Available building blocks: DSF, LEARNING, ORDER, PHASE, RESTARTS, SIMP, PARAMS"); log("Example: -S RESTARTS=org.sat4j.minisat.restarts.LubyRestarts/factor:512,LEARNING=org.sat4j.minisat.learning.MiniSATLearning"); } @SuppressWarnings("unchecked") private final T setupObject(String component, Properties pf) { try { String configline = pf.getProperty(component); if (configline == null) { return null; } log("configuring " + component); String[] config = configline.split("/"); T comp = (T) Class.forName(config[0]).newInstance(); for (int i = 1; i < config.length; i++) { String[] param = config[i].split(":"); //$NON-NLS-1$ assert param.length == 2; try { // Check first that the property really exists BeanUtils.getProperty(comp, param[0]); BeanUtils.setProperty(comp, param[0], param[1]); } catch (Exception e) { log("Problem with component " + config[0] + " " + e); } } return comp; } catch (InstantiationException e) { log("Problem with component " + component + " " + e); } catch (IllegalAccessException e) { log("Problem with component " + component + " " + e); } catch (ClassNotFoundException e) { log("Problem with component " + component + " " + e); } return null; } @Override protected IProblem readProblem(String problemname) throws FileNotFoundException, ParseFormatException, IOException, ContradictionException { ISolver theSolver = (ISolver) super.readProblem(problemname); if (k > 0) { IVecInt literals = new VecInt(); for (int i = 1; i <= theSolver.nVars(); i++) { literals.push(-i); } theSolver.addAtLeast(literals, k); log("Limiting solutions to those having at least " + k + " variables assigned to false"); } return theSolver; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy