Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*******************************************************************************
- * SAT4J: a SATisfiability library for Java Copyright (C) 2004, 2012 Artois University and CNRS
- *
- * 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.
- *
- * Based on the original MiniSat specification from:
- *
- * An extensible SAT solver. Niklas Een and Niklas Sorensson. Proceedings of the
- * Sixth International Conference on Theory and Applications of Satisfiability
- * Testing, LNCS 2919, pp 502-518, 2003.
- *
- * See www.minisat.se for the original solver in C++.
- *
- * Contributors:
- * CRIL - initial API and implementation
- *******************************************************************************/
- package org.sat4j.minisat.core;
- import static org.sat4j.core.LiteralsUtils.neg;
- import static org.sat4j.core.LiteralsUtils.toDimacs;
- import static org.sat4j.core.LiteralsUtils.toInternal;
- import static org.sat4j.core.LiteralsUtils.var;
- import java.io.PrintStream;
- import java.io.PrintWriter;
- import java.lang.reflect.Field;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import java.util.Timer;
- import java.util.TimerTask;
- import org.sat4j.core.ConstrGroup;
- import org.sat4j.core.LiteralsUtils;
- import org.sat4j.core.Vec;
- import org.sat4j.core.VecInt;
- import org.sat4j.specs.ContradictionException;
- import org.sat4j.specs.IConstr;
- import org.sat4j.specs.ILogAble;
- import org.sat4j.specs.ISolver;
- import org.sat4j.specs.ISolverService;
- import org.sat4j.specs.IVec;
- import org.sat4j.specs.IVecInt;
- import org.sat4j.specs.IteratorInt;
- import org.sat4j.specs.Lbool;
- import org.sat4j.specs.SearchListener;
- import org.sat4j.specs.TimeoutException;
- import org.sat4j.specs.UnitClauseProvider;
- /**
- * The backbone of the library providing the modular implementation of a MiniSAT
- * (Chaff) like solver.
- *
- * @author leberre
- */
- public class Solver<D extends DataStructureFactory> implements ISolverService,
- ICDCL<D> {
- private static final long serialVersionUID = 1L;
- private static final double CLAUSE_RESCALE_FACTOR = 1e-20;
- private static final double CLAUSE_RESCALE_BOUND = 1 / CLAUSE_RESCALE_FACTOR;
- protected ILogAble out;
- /**
- * Set of original constraints.
- */
- protected final IVec<Constr> constrs = new Vec<Constr>();
- /**
- * Set of learned constraints.
- */
- protected final IVec<Constr> learnts = new Vec<Constr>();
- /**
- * Increment for clause activity.
- */
- private double claInc = 1.0;
- /**
- * decay factor pour l'activit? des clauses.
- */
- private double claDecay = 1.0;
- /**
- * propagation queue
- */
- // head of the queue in trail ... (taken from MiniSAT 1.14)
- private int qhead = 0;
- /**
- * variable assignments (literals) in chronological order.
- */
- protected final IVecInt trail = new VecInt();
- /**
- * position of the decision levels on the trail.
- */
- protected final IVecInt trailLim = new VecInt();
- /**
- * position of assumptions before starting the search.
- */
- protected int rootLevel;
- private int[] model = null;
- protected ILits voc;
- private IOrder order;
- private final ActivityComparator comparator = new ActivityComparator();
- private SolverStats stats = new SolverStats();
- private LearningStrategy<D> learner;
- protected volatile boolean undertimeout;
- private long timeout = Integer.MAX_VALUE;
- private boolean timeBasedTimeout = true;
- protected D dsfactory;
- private SearchParams params;
- private final IVecInt __dimacs_out = new VecInt();
- protected SearchListener slistener = new VoidTracing();
- private RestartStrategy restarter;
- private final Map<String, Counter> constrTypes = new HashMap<String, Counter>();
- private boolean isDBSimplificationAllowed = false;
- private final IVecInt learnedLiterals = new VecInt();
- private boolean verbose = false;
- private boolean keepHot = false;
- private String prefix = "c ";
- private int declaredMaxVarId = 0;
- private UnitClauseProvider unitClauseProvider = UnitClauseProvider.VOID;
- protected IVecInt dimacs2internal(IVecInt in) {
- this.__dimacs_out.clear();
- this.__dimacs_out.ensure(in.size());
- int p;
- for (int i = 0; i < in.size(); i++) {
- p = in.get(i);
- if (p == 0) {
- throw new IllegalArgumentException(
- "0 is not a valid variable identifier");
- }
- this.__dimacs_out.unsafePush(this.voc.getFromPool(p));
- }
- return this.__dimacs_out;
- }
- /*
- * @since 2.3.1
- */
- public void registerLiteral(int p) {
- this.voc.getFromPool(p);
- }
- /**
- * creates a Solver without LearningListener. A learningListener must be
- * added to the solver, else it won't backtrack!!! A data structure factory
- * must be provided, else it won't work either.
- */
- public Solver(LearningStrategy<D> learner, D dsf, IOrder order,
- RestartStrategy restarter) {
- this(learner, dsf, new SearchParams(), order, restarter);
- }
- public Solver(LearningStrategy<D> learner, D dsf, SearchParams params,
- IOrder order, RestartStrategy restarter) {
- this(learner, dsf, params, order, restarter, ILogAble.CONSOLE);
- }
- public Solver(LearningStrategy<D> learner, D dsf, SearchParams params,
- IOrder order, RestartStrategy restarter, ILogAble logger) {
- this.order = order;
- this.params = params;
- this.restarter = restarter;
- this.out = logger;
- setDataStructureFactory(dsf);
- // should be called after dsf has been set up
- setLearningStrategy(learner);
- }
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.minisat.core.ICDCL#setDataStructureFactory(D)
- */
- public final void setDataStructureFactory(D dsf) {
- this.dsfactory = dsf;
- this.dsfactory.setUnitPropagationListener(this);
- this.dsfactory.setLearner(this);
- this.voc = dsf.getVocabulary();
- this.order.setLits(this.voc);
- }
- /**
- * @since 2.2
- */
- public boolean isVerbose() {
- return this.verbose;
- }
- /**
- * @param value
- * @since 2.2
- */
- public void setVerbose(boolean value) {
- this.verbose = value;
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * org.sat4j.minisat.core.ICDCL#setSearchListener(org.sat4j.specs.SearchListener
- * )
- */
- public <S extends ISolverService> void setSearchListener(
- SearchListener<S> sl) {
- this.slistener = sl;
- }
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.minisat.core.ICDCL#getSearchListener()
- */
- public <S extends ISolverService> SearchListener<S> getSearchListener() {
- return this.slistener;
- }
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.minisat.core.ICDCL#setLearner(org.sat4j.minisat.core.
- * LearningStrategy)
- */
- public void setLearner(LearningStrategy<D> strategy) {
- setLearningStrategy(strategy);
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * org.sat4j.minisat.core.ICDCL#setLearningStrategy(org.sat4j.minisat.core.
- * LearningStrategy)
- */
- public void setLearningStrategy(LearningStrategy<D> strategy) {
- if (this.learner != null) {
- this.learner.setSolver(null);
- }
- this.learner = strategy;
- strategy.setSolver(this);
- }
- public void setTimeout(int t) {
- this.timeout = t * 1000L;
- this.timeBasedTimeout = true;
- }
- public void setTimeoutMs(long t) {
- this.timeout = t;
- this.timeBasedTimeout = true;
- }
- public void setTimeoutOnConflicts(int count) {
- this.timeout = count;
- this.timeBasedTimeout = false;
- }
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.minisat.core.ICDCL#setSearchParams(org.sat4j.minisat.core.
- * SearchParams)
- */
- public void setSearchParams(SearchParams sp) {
- this.params = sp;
- }
- public SearchParams getSearchParams() {
- return this.params;
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * org.sat4j.minisat.core.ICDCL#setRestartStrategy(org.sat4j.minisat.core
- * .RestartStrategy)
- */
- public void setRestartStrategy(RestartStrategy restarter) {
- this.restarter = restarter;
- }
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.minisat.core.ICDCL#getRestartStrategy()
- */
- public RestartStrategy getRestartStrategy() {
- return this.restarter;
- }
- public void expireTimeout() {
- this.undertimeout = false;
- if (this.timeBasedTimeout) {
- if (this.timer != null) {
- this.timer.cancel();
- this.timer = null;
- }
- } else {
- if (this.conflictCount != null) {
- this.conflictCount = null;
- }
- }
- }
- protected int nAssigns() {
- return this.trail.size();
- }
- public int nConstraints() {
- return this.constrs.size();
- }
- public void learn(Constr c) {
- this.slistener.learn(c);
- this.learnts.push(c);
- c.setLearnt();
- c.register();
- this.stats.learnedclauses++;
- switch (c.size()) {
- case 2:
- this.stats.learnedbinaryclauses++;
- break;
- case 3:
- this.stats.learnedternaryclauses++;
- break;
- default:
- // do nothing
- }
- }
- public final int decisionLevel() {
- return this.trailLim.size();
- }
- @Deprecated
- public int newVar() {
- int index = this.voc.nVars() + 1;
- this.voc.ensurePool(index);
- return index;
- }
- public int newVar(int howmany) {
- this.voc.ensurePool(howmany);
- this.declaredMaxVarId = howmany;
- return howmany;
- }
- public IConstr addClause(IVecInt literals) throws ContradictionException {
- IVecInt vlits = dimacs2internal(literals);
- return addConstr(this.dsfactory.createClause(vlits));
- }
- public boolean removeConstr(IConstr co) {
- if (co == null) {
- throw new IllegalArgumentException(
- "Reference to the constraint to remove needed!"); //$NON-NLS-1$
- }
- Constr c = (Constr) co;
- c.remove(this);
- this.constrs.remove(c);
- clearLearntClauses();
- String type = c.getClass().getName();
- this.constrTypes.get(type).dec();
- return true;
- }
- /**
- * @since 2.1
- */
- public boolean removeSubsumedConstr(IConstr co) {
- if (co == null) {
- throw new IllegalArgumentException(
- "Reference to the constraint to remove needed!"); //$NON-NLS-1$
- }
- if (this.constrs.last() != co) {
- throw new IllegalArgumentException(
- "Can only remove latest added constraint!!!"); //$NON-NLS-1$
- }
- Constr c = (Constr) co;
- c.remove(this);
- this.constrs.pop();
- String type = c.getClass().getName();
- this.constrTypes.get(type).dec();
- return true;
- }
- public void addAllClauses(IVec<IVecInt> clauses)
- throws ContradictionException {
- for (Iterator<IVecInt> iterator = clauses.iterator(); iterator
- .hasNext();) {
- addClause(iterator.next());
- }
- }
- public IConstr addAtMost(IVecInt literals, int degree)
- throws ContradictionException {
- int n = literals.size();
- IVecInt opliterals = new VecInt(n);
- for (IteratorInt iterator = literals.iterator(); iterator.hasNext();) {
- opliterals.push(-iterator.next());
- }
- return addAtLeast(opliterals, n - degree);
- }
- public IConstr addAtLeast(IVecInt literals, int degree)
- throws ContradictionException {
- IVecInt vlits = dimacs2internal(literals);
- return addConstr(this.dsfactory.createCardinalityConstraint(vlits,
- degree));
- }
- public IConstr addExactly(IVecInt literals, int n)
- throws ContradictionException {
- ConstrGroup group = new ConstrGroup(false);
- group.add(addAtMost(literals, n));
- group.add(addAtLeast(literals, n));
- return group;
- }
- @SuppressWarnings("unchecked")
- public boolean simplifyDB() {
- // Simplifie la base de clauses apres la premiere propagation des
- // clauses unitaires
- IVec<Constr>[] cs = new IVec[] { this.constrs, this.learnts };
- for (int type = 0; type < 2; type++) {
- int j = 0;
- for (int i = 0; i < cs[type].size(); i++) {
- if (cs[type].get(i).simplify()) {
- // enleve les contraintes satisfaites de la base
- cs[type].get(i).remove(this);
- } else {
- cs[type].moveTo(j++, i);
- }
- }
- cs[type].shrinkTo(j);
- }
- return true;
- }
- /**
- * Si un mod?le est trouv?, ce vecteur contient le mod?le.
- *
- * @return un mod?le de la formule.
- */
- public int[] model() {
- if (this.model == null) {
- throw new UnsupportedOperationException(
- "Call the solve method first!!!"); //$NON-NLS-1$
- }
- int[] nmodel = new int[this.model.length];
- System.arraycopy(this.model, 0, nmodel, 0, this.model.length);
- return nmodel;
- }
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.minisat.core.ICDCL#enqueue(int)
- */
- public boolean enqueue(int p) {
- return enqueue(p, null);
- }
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.minisat.core.ICDCL#enqueue(int,
- * org.sat4j.minisat.core.Constr)
- */
- public boolean enqueue(int p, Constr from) {
- assert p > 1;
- if (this.voc.isSatisfied(p)) {
- // literal is already satisfied. Skipping.
- return true;
- }
- if (this.voc.isFalsified(p)) {
- // conflicting enqueued assignment
- return false;
- }
- // new fact, store it
- this.voc.satisfies(p);
- this.voc.setLevel(p, decisionLevel());
- this.voc.setReason(p, from);
- this.trail.push(p);
- if (from != null && from.learnt()) {
- this.learnedConstraintsDeletionStrategy.onPropagation(from);
- }
- return true;
- }
- private boolean[] mseen = new boolean[0];
- private final IVecInt mpreason = new VecInt();
- private final IVecInt moutLearnt = new VecInt();
- /**
- * @throws TimeoutException
- * if the timeout is reached during conflict analysis.
- */
- public void analyze(Constr confl, Pair results) throws TimeoutException {
- assert confl != null;
- final boolean[] seen = this.mseen;
- final IVecInt outLearnt = this.moutLearnt;
- final IVecInt preason = this.mpreason;
- outLearnt.clear();
- assert outLearnt.size() == 0;
- for (int i = 0; i < seen.length; i++) {
- seen[i] = false;
- }
- int counter = 0;
- int p = ILits.UNDEFINED;
- outLearnt.push(ILits.UNDEFINED);
- // reserve de la place pour le litteral falsifie
- int outBtlevel = 0;
- IConstr prevConfl = null;
- do {
- preason.clear();
- assert confl != null;
- if (prevConfl != confl) {
- confl.calcReason(p, preason);
- this.learnedConstraintsDeletionStrategy
- .onConflictAnalysis(confl);
- // Trace reason for p
- for (int j = 0; j < preason.size(); j++) {
- int q = preason.get(j);
- this.order.updateVar(q);
- if (!seen[q >> 1]) {
- seen[q >> 1] = true;
- if (this.voc.getLevel(q) == decisionLevel()) {
- counter++;
- this.order.updateVarAtDecisionLevel(q);
- } else if (this.voc.getLevel(q) > 0) {
- // only literals assigned after decision level 0
- // part of
- // the explanation
- outLearnt.push(q ^ 1);
- outBtlevel = Math.max(outBtlevel,
- this.voc.getLevel(q));
- }
- }
- }
- }
- prevConfl = confl;
- // select next reason to look at
- do {
- p = this.trail.last();
- confl = this.voc.getReason(p);
- undoOne();
- } while (!seen[p >> 1]);
- // seen[p.var] indique que p se trouve dans outLearnt ou dans
- // le dernier niveau de d?cision
- } while (--counter > 0);
- outLearnt.set(0, p ^ 1);
- this.simplifier.simplify(outLearnt);
- Constr c = this.dsfactory.createUnregisteredClause(outLearnt);
- // slistener.learn(c);
- this.learnedConstraintsDeletionStrategy.onClauseLearning(c);
- results.reason = c;
- assert outBtlevel > -1;
- results.backtrackLevel = outBtlevel;
- }
- /**
- * Derive a subset of the assumptions causing the inconistency.
- *
- * @param confl
- * the last conflict of the search, occuring at root level.
- * @param assumps
- * the set of assumption literals
- * @param conflictingLiteral
- * the literal detected conflicting while propagating
- * assumptions.
- * @return a subset of assumps causing the inconsistency.
- * @since 2.2
- */
- public IVecInt analyzeFinalConflictInTermsOfAssumptions(Constr confl,
- IVecInt assumps, int conflictingLiteral) {
- if (assumps.size() == 0) {
- return null;
- }
- while (!this.trailLim.isEmpty()
- && this.trailLim.last() == this.trail.size()) {
- // conflict detected when assuming a value
- this.trailLim.pop();
- }
- final boolean[] seen = this.mseen;
- final IVecInt outLearnt = this.moutLearnt;
- final IVecInt preason = this.mpreason;
- outLearnt.clear();
- if (this.trailLim.size() == 0) {
- // conflict detected on unit clauses
- return outLearnt;
- }
- assert outLearnt.size() == 0;
- for (int i = 0; i < seen.length; i++) {
- seen[i] = false;
- }
- if (confl == null) {
- seen[conflictingLiteral >> 1] = true;
- }
- int p = ILits.UNDEFINED;
- while (confl == null && this.trail.size() > 0
- && this.trailLim.size() > 0) {
- p = this.trail.last();
- confl = this.voc.getReason(p);
- undoOne();
- if (confl == null && p == (conflictingLiteral ^ 1)) {
- outLearnt.push(toDimacs(p));
- }
- if (this.trail.size() <= this.trailLim.last()) {
- this.trailLim.pop();
- }
- }
- if (confl == null) {
- return outLearnt;
- }
- do {
- preason.clear();
- confl.calcReason(p, preason);
- // Trace reason for p
- for (int j = 0; j < preason.size(); j++) {
- int q = preason.get(j);
- if (!seen[q >> 1]) {
- seen[q >> 1] = true;
- if (this.voc.getReason(q) == null
- && this.voc.getLevel(q) > 0) {
- assert assumps.contains(toDimacs(q));
- outLearnt.push(toDimacs(q));
- }
- }
- }
- // select next reason to look at
- do {
- p = this.trail.last();
- confl = this.voc.getReason(p);
- undoOne();
- if (decisionLevel() > 0
- && this.trail.size() <= this.trailLim.last()) {
- this.trailLim.pop();
- }
- } while (this.trail.size() > 0 && decisionLevel() > 0
- && (!seen[p >> 1] || confl == null));
- } while (decisionLevel() > 0);
- return outLearnt;
- }
- public static final ISimplifier NO_SIMPLIFICATION = new ISimplifier() {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- public void simplify(IVecInt outLearnt) {
- }
- @Override
- public String toString() {
- return "No reason simplification"; //$NON-NLS-1$
- }
- };
- public final ISimplifier SIMPLE_SIMPLIFICATION = new ISimplifier() {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- public void simplify(IVecInt conflictToReduce) {
- simpleSimplification(conflictToReduce);
- }
- @Override
- public String toString() {
- return "Simple reason simplification"; //$NON-NLS-1$
- }
- };
- public final ISimplifier EXPENSIVE_SIMPLIFICATION = new ISimplifier() {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- public void simplify(IVecInt conflictToReduce) {
- expensiveSimplification(conflictToReduce);
- }
- @Override
- public String toString() {
- return "Expensive reason simplification"; //$NON-NLS-1$
- }
- };
- public final ISimplifier EXPENSIVE_SIMPLIFICATION_WLONLY = new ISimplifier() {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- public void simplify(IVecInt conflictToReduce) {
- expensiveSimplificationWLOnly(conflictToReduce);
- }
- @Override
- public String toString() {
- return "Expensive reason simplification specific for WL data structure"; //$NON-NLS-1$
- }
- };
- private ISimplifier simplifier = NO_SIMPLIFICATION;
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.minisat.core.ICDCL#setSimplifier(java.lang.String)
- */
- public void setSimplifier(SimplificationType simp) {
- Field f;
- try {
- f = Solver.class.getDeclaredField(simp.toString());
- this.simplifier = (ISimplifier) f.get(this);
- } catch (Exception e) {
- e.printStackTrace();
- this.simplifier = NO_SIMPLIFICATION;
- }
- }
- /*
- * (non-Javadoc)
- *
- * @see
- * org.sat4j.minisat.core.ICDCL#setSimplifier(org.sat4j.minisat.core.Solver
- * .ISimplifier)
- */
- public void setSimplifier(ISimplifier simp) {
- this.simplifier = simp;
- }
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.minisat.core.ICDCL#getSimplifier()
- */
- public ISimplifier getSimplifier() {
- return this.simplifier;
- }
- // MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
- //
- // 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.
- // Taken from MiniSAT 1.14: Simplify conflict clause (a little):
- private void simpleSimplification(IVecInt conflictToReduce) {
- int i, j, p;
- final boolean[] seen = this.mseen;
- IConstr r;
- for (i = j = 1; i < conflictToReduce.size(); i++) {
- r = this.voc.getReason(conflictToReduce.get(i));
- if (r == null || r.canBePropagatedMultipleTimes()) {
- conflictToReduce.moveTo(j++, i);
- } else {
- for (int k = 0; k < r.size(); k++) {
- p = r.get(k);
- if (!seen[p >> 1] && this.voc.isFalsified(p)
- && this.voc.getLevel(p) != 0) {
- conflictToReduce.moveTo(j++, i);
- break;
- }
- }
- }
- }
- conflictToReduce.shrink(i - j);
- this.stats.reducedliterals += i - j;
- }
- private final IVecInt analyzetoclear = new VecInt();
- private final IVecInt analyzestack = new VecInt();
- // Taken from MiniSAT 1.14
- private void expensiveSimplification(IVecInt conflictToReduce) {
- // Simplify conflict clause (a lot):
- //
- int i, j;
- // (maintain an abstraction of levels involved in conflict)
- this.analyzetoclear.clear();
- conflictToReduce.copyTo(this.analyzetoclear);
- for (i = 1, j = 1; i < conflictToReduce.size(); i++) {
- if (this.voc.getReason(conflictToReduce.get(i)) == null
- || !analyzeRemovable(conflictToReduce.get(i))) {
- conflictToReduce.moveTo(j++, i);
- }
- }
- conflictToReduce.shrink(i - j);
- this.stats.reducedliterals += i - j;
- }
- // Check if 'p' can be removed.' min_level' is used to abort early if
- // visiting literals at a level that cannot be removed.
- //
- private boolean analyzeRemovable(int p) {
- assert this.voc.getReason(p) != null;
- ILits lvoc = this.voc;
- IVecInt lanalyzestack = this.analyzestack;
- IVecInt lanalyzetoclear = this.analyzetoclear;
- lanalyzestack.clear();
- lanalyzestack.push(p);
- final boolean[] seen = this.mseen;
- int top = lanalyzetoclear.size();
- while (lanalyzestack.size() > 0) {
- int q = lanalyzestack.last();
- assert lvoc.getReason(q) != null;
- Constr c = lvoc.getReason(q);
- lanalyzestack.pop();
- if (c.canBePropagatedMultipleTimes()) {
- for (int j = top; j < lanalyzetoclear.size(); j++) {
- seen[lanalyzetoclear.get(j) >> 1] = false;
- }
- lanalyzetoclear.shrink(lanalyzetoclear.size() - top);
- return false;
- }
- for (int i = 0; i < c.size(); i++) {
- int l = c.get(i);
- if (!seen[var(l)] && lvoc.isFalsified(l)
- && lvoc.getLevel(l) != 0) {
- if (lvoc.getReason(l) == null) {
- for (int j = top; j < lanalyzetoclear.size(); j++) {
- seen[lanalyzetoclear.get(j) >> 1] = false;
- }
- lanalyzetoclear.shrink(lanalyzetoclear.size() - top);
- return false;
- }
- seen[l >> 1] = true;
- lanalyzestack.push(l);
- lanalyzetoclear.push(l);
- }
- }
- }
- return true;
- }
- // Taken from MiniSAT 1.14
- private void expensiveSimplificationWLOnly(IVecInt conflictToReduce) {
- // Simplify conflict clause (a lot):
- //
- int i, j;
- // (maintain an abstraction of levels involved in conflict)
- this.analyzetoclear.clear();
- conflictToReduce.copyTo(this.analyzetoclear);
- for (i = 1, j = 1; i < conflictToReduce.size(); i++) {
- if (this.voc.getReason(conflictToReduce.get(i)) == null
- || !analyzeRemovableWLOnly(conflictToReduce.get(i))) {
- conflictToReduce.moveTo(j++, i);
- }
- }
- conflictToReduce.shrink(i - j);
- this.stats.reducedliterals += i - j;
- }
- // Check if 'p' can be removed.' min_level' is used to abort early if
- // visiting literals at a level that cannot be removed.
- //
- private boolean analyzeRemovableWLOnly(int p) {
- assert this.voc.getReason(p) != null;
- this.analyzestack.clear();
- this.analyzestack.push(p);
- final boolean[] seen = this.mseen;
- int top = this.analyzetoclear.size();
- while (this.analyzestack.size() > 0) {
- int q = this.analyzestack.last();
- assert this.voc.getReason(q) != null;
- Constr c = this.voc.getReason(q);
- this.analyzestack.pop();
- for (int i = 1; i < c.size(); i++) {
- int l = c.get(i);
- if (!seen[var(l)] && this.voc.getLevel(l) != 0) {
- if (this.voc.getReason(l) == null) {
- for (int j = top; j < this.analyzetoclear.size(); j++) {
- seen[this.analyzetoclear.get(j) >> 1] = false;
- }
- this.analyzetoclear.shrink(this.analyzetoclear.size()
- - top);
- return false;
- }
- seen[l >> 1] = true;
- this.analyzestack.push(l);
- this.analyzetoclear.push(l);
- }
- }
- }
- return true;
- }
- // END Minisat 1.14 cut and paste
- /**
- *
- */
- protected void undoOne() {
- // gather last assigned literal
- int p = this.trail.last();
- assert p > 1;
- assert this.voc.getLevel(p) >= 0;
- int x = p >> 1;
- // unassign variable
- this.voc.unassign(p);
- this.voc.setReason(p, null);
- this.voc.setLevel(p, -1);
- // update heuristics value
- this.order.undo(x);
- // remove literal from the trail
- this.trail.pop();
- // update constraints on backtrack.
- // not used if the solver uses watched literals.
- IVec<Undoable> undos = this.voc.undos(p);
- assert undos != null;
- for (int size = undos.size(); size > 0; size--) {
- undos.last().undo(p);
- undos.pop();
- }
- }
- /**
- * Propagate activity to a constraint
- *
- * @param confl
- * a constraint
- */
- public void claBumpActivity(Constr confl) {
- confl.incActivity(this.claInc);
- if (confl.getActivity() > CLAUSE_RESCALE_BOUND) {
- claRescalActivity();
- // for (int i = 0; i < confl.size(); i++) {
- // varBumpActivity(confl.get(i));
- // }
- }
- }
- public void varBumpActivity(int p) {
- this.order.updateVar(p);
- }
- private void claRescalActivity() {
- for (int i = 0; i < this.learnts.size(); i++) {
- this.learnts.get(i).rescaleBy(CLAUSE_RESCALE_FACTOR);
- }
- this.claInc *= CLAUSE_RESCALE_FACTOR;
- }
- private final IVec<Propagatable> watched = new Vec<Propagatable>();
- /**
- * @return null if not conflict is found, else a conflicting constraint.
- */
- public final Constr propagate() {
- IVecInt ltrail = this.trail;
- SolverStats lstats = this.stats;
- IOrder lorder = this.order;
- SearchListener lslistener = this.slistener;
- // ltrail.size() changes due to propagation
- // cannot cache that value.
- while (this.qhead < ltrail.size()) {
- lstats.propagations++;
- int p = ltrail.get(this.qhead++);
- lslistener.propagating(toDimacs(p), null);
- lorder.assignLiteral(p);
- Constr confl = reduceClausesForFalsifiedLiteral(p);
- if (confl != null) {
- return confl;
- }
- }
- return null;
- }
- private Constr reduceClausesForFalsifiedLiteral(int p) {
- // p is the literal to propagate
- // Moved original MiniSAT code to dsfactory to avoid
- // watches manipulation in counter Based clauses for instance.
- assert p > 1;
- IVec<Propagatable> lwatched = this.watched;
- lwatched.clear();
- this.voc.watches(p).moveTo(lwatched);
- final int size = lwatched.size();
- for (int i = 0; i < size; i++) {
- this.stats.inspects++;
- // try shortcut
- // shortcut = shortcuts.get(i);
- // if (shortcut != ILits.UNDEFINED && voc.isSatisfied(shortcut))
- // {
- // voc.watch(p, watched.get(i), shortcut);
- // stats.shortcuts++;
- // continue;
- // }
- if (!lwatched.get(i).propagate(this, p)) {
- // Constraint is conflicting: copy remaining watches to
- // watches[p]
- // and return constraint
- final int sizew = lwatched.size();
- for (int j = i + 1; j < sizew; j++) {
- this.voc.watch(p, lwatched.get(j));
- }
- this.qhead = this.trail.size(); // propQ.clear();
- return lwatched.get(i).toConstraint();
- }
- }
- return null;
- }
- void record(Constr constr) {
- constr.assertConstraint(this);
- int p = toDimacs(constr.get(0));
- this.slistener.adding(p);
- if (constr.size() == 1) {
- this.stats.learnedliterals++;
- this.slistener.learnUnit(p);
- } else {
- this.learner.learns(constr);
- }
- }
- /**
- * @return false ssi conflit imm?diat.
- */
- public boolean assume(int p) {
- // Precondition: assume propagation queue is empty
- assert this.trail.size() == this.qhead;
- assert !this.trailLim.contains(this.trail.size());
- this.trailLim.push(this.trail.size());
- return enqueue(p);
- }
- /**
- * Revert to the state before the last assume()
- */
- private void cancel() {
- // assert trail.size() == qhead || !undertimeout;
- int decisionvar = this.trail.unsafeGet(this.trailLim.last());
- this.slistener.backtracking(toDimacs(decisionvar));
- for (int c = this.trail.size() - this.trailLim.last(); c > 0; c--) {
- undoOne();
- }
- this.trailLim.pop();
- this.qhead = this.trail.size();
- }
- /**
- * Restore literals
- */
- private void cancelLearntLiterals(int learnedLiteralsLimit) {
- this.learnedLiterals.clear();
- // assert trail.size() == qhead || !undertimeout;
- while (this.trail.size() > learnedLiteralsLimit) {
- this.learnedLiterals.push(this.trail.last());
- undoOne();
- }
- // qhead = 0;
- // learnedLiterals = 0;
- }
- /**
- * Cancel several levels of assumptions
- *
- * @param level
- */
- protected void cancelUntil(int level) {
- while (decisionLevel() > level) {
- cancel();
- }
- }
- private final Pair analysisResult = new Pair();
- private boolean[] userbooleanmodel;
- private IVecInt unsatExplanationInTermsOfAssumptions;
- Lbool search(IVecInt assumps) {
- assert this.rootLevel == decisionLevel();
- this.stats.starts++;
- int backjumpLevel;
- // varDecay = 1 / params.varDecay;
- this.order.setVarDecay(1 / this.params.getVarDecay());
- this.claDecay = 1 / this.params.getClaDecay();
- do {
- this.slistener.beginLoop();
- // propagate unit clauses and other constraints
- Constr confl = propagate();
- assert this.trail.size() == this.qhead;
- if (confl == null) {
- // No conflict found
- if (decisionLevel() == 0 && this.isDBSimplificationAllowed) {
- this.stats.rootSimplifications++;
- boolean ret = simplifyDB();
- assert ret;
- }
- assert nAssigns() <= this.voc.realnVars();
- if (nAssigns() == this.voc.realnVars()) {
- modelFound();
- this.slistener.solutionFound(
- (this.fullmodel != null) ? this.fullmodel
- : this.model, this);
- if (this.sharedConflict == null) {
- cancelUntil(this.rootLevel);
- return Lbool.TRUE;
- } else {
- confl = this.sharedConflict;
- }
- } else {
- if (this.restarter.shouldRestart()) {
- cancelUntil(this.rootLevel);
- return Lbool.UNDEFINED;
- }
- if (this.needToReduceDB) {
- reduceDB();
- this.needToReduceDB = false;
- }
- if (this.sharedConflict == null) {
- // New variable decision
- this.stats.decisions++;
- int p = this.order.select();
- if (p == ILits.UNDEFINED) {
- confl = preventTheSameDecisionsToBeMade();
- this.lastConflictMeansUnsat = false;
- } else {
- assert p > 1;
- this.slistener.assuming(toDimacs(p));
- boolean ret = assume(p);
- assert ret;
- }
- } else {
- confl = this.sharedConflict;
- }
- }
- }
- if (confl != null) {
- // conflict found
- this.stats.conflicts++;
- this.slistener.conflictFound(confl, decisionLevel(),
- this.trail.size());
- this.conflictCount.newConflict();
- if (decisionLevel() == this.rootLevel) {
- if (this.lastConflictMeansUnsat) {
- // conflict at root level, the formula is inconsistent
- this.unsatExplanationInTermsOfAssumptions = analyzeFinalConflictInTermsOfAssumptions(
- confl, assumps, ILits.UNDEFINED);
- return Lbool.FALSE;
- }
- return Lbool.UNDEFINED;
- }
- int conflictTrailLevel = this.trail.size();
- // analyze conflict
- try {
- analyze(confl, this.analysisResult);
- } catch (TimeoutException e) {
- return Lbool.UNDEFINED;
- }
- assert this.analysisResult.backtrackLevel < decisionLevel();
- backjumpLevel = Math.max(this.analysisResult.backtrackLevel,
- this.rootLevel);
- this.slistener.backjump(backjumpLevel);
- cancelUntil(backjumpLevel);
- if (backjumpLevel == this.rootLevel) {
- this.restarter.onBackjumpToRootLevel();
- }
- if (confl == this.sharedConflict) {
- this.sharedConflict.assertConstraintIfNeeded(this);
- this.sharedConflict = null;
- }
- assert decisionLevel() >= this.rootLevel
- && decisionLevel() >= this.analysisResult.backtrackLevel;
- if (this.analysisResult.reason == null) {
- return Lbool.FALSE;
- }
- record(this.analysisResult.reason);
- this.restarter.newLearnedClause(this.analysisResult.reason,
- conflictTrailLevel);
- this.analysisResult.reason = null;
- decayActivities();
- }
- } while (this.undertimeout);
- return Lbool.UNDEFINED; // timeout occured
- }
- private Constr preventTheSameDecisionsToBeMade() {
- IVecInt clause = new VecInt(nVars());
- int p;
- for (int i = this.trail.size() - 1; i >= this.rootLevel; i--) {
- p = this.trail.get(i);
- if (this.voc.getReason(p) == null) {
- clause.push(p ^ 1);
- }
- }
- return this.dsfactory.createUnregisteredClause(clause);
- }
- protected void analyzeAtRootLevel(Constr conflict) {
- }
- private final IVecInt implied = new VecInt();
- private final IVecInt decisions = new VecInt();
- private int[] fullmodel;
- /**
- *
- */
- void modelFound() {
- IVecInt tempmodel = new VecInt(nVars());
- this.userbooleanmodel = new boolean[realNumberOfVariables()];
- this.fullmodel = null;
- for (int i = 1; i <= nVars(); i++) {
- if (this.voc.belongsToPool(i)) {
- int p = this.voc.getFromPool(i);
- if (!this.voc.isUnassigned(p)) {
- tempmodel.push(this.voc.isSatisfied(p) ? i : -i);
- this.userbooleanmodel[i - 1] = this.voc.isSatisfied(p);
- if (this.voc.getReason(p) == null && voc.getLevel(p) > 0) {
- this.decisions.push(tempmodel.last());
- } else {
- this.implied.push(tempmodel.last());
- }
- }
- }
- }
- this.model = new int[tempmodel.size()];
- tempmodel.copyTo(this.model);
- if (realNumberOfVariables() > nVars()) {
- for (int i = nVars() + 1; i <= realNumberOfVariables(); i++) {
- if (this.voc.belongsToPool(i)) {
- int p = this.voc.getFromPool(i);
- if (!this.voc.isUnassigned(p)) {
- tempmodel.push(this.voc.isSatisfied(p) ? i : -i);
- this.userbooleanmodel[i - 1] = this.voc.isSatisfied(p);
- if (this.voc.getReason(p) == null) {
- this.decisions.push(tempmodel.last());
- } else {
- this.implied.push(tempmodel.last());
- }
- }
- }
- }
- this.fullmodel = new int[tempmodel.size()];
- tempmodel.moveTo(this.fullmodel);
- } else {
- this.fullmodel = this.model;
- }
- }
- /**
- * Forget a variable in the formula by falsifying both its positive and
- * negative literals.
- *
- * @param var
- * a variable
- * @return a conflicting constraint resulting from the disparition of those
- * literals.
- */
- private Constr forget(int var) {
- boolean satisfied = this.voc.isSatisfied(toInternal(var));
- this.voc.forgets(var);
- Constr confl;
- if (satisfied) {
- confl = reduceClausesForFalsifiedLiteral(LiteralsUtils
- .toInternal(-var));
- } else {
- confl = reduceClausesForFalsifiedLiteral(LiteralsUtils
- .toInternal(var));
- }
- return confl;
- }
- /**
- * Assume literal p and perform unit propagation
- *
- * @param p
- * a literal
- * @return true if no conflict is reached, false if a conflict is found.
- */
- private boolean setAndPropagate(int p) {
- if (voc.isUnassigned(p)) {
- assert !trail.contains(p);
- assert !trail.contains(neg(p));
- return assume(p) && propagate() == null;
- }
- return voc.isSatisfied(p);
- }
- private int[] prime;
- public int[] primeImplicant() {
- assert this.qhead == this.trail.size() + this.learnedLiterals.size();
- if (this.learnedLiterals.size() > 0) {
- this.qhead = trail.size();
- }
- if (isVerbose()) {
- System.out.printf("%s implied: %d, decision: %d %n",
- getLogPrefix(), implied.size(), decisions.size());
- }
- this.prime = new int[realNumberOfVariables() + 1];
- int p, d;
- for (int i = 0; i < this.prime.length; i++) {
- this.prime[i] = 0;
- }
- boolean noproblem;
- for (IteratorInt it = this.implied.iterator(); it.hasNext();) {
- d = it.next();
- p = toInternal(d);
- this.prime[Math.abs(d)] = d;
- noproblem = setAndPropagate(p);
- assert noproblem;
- }
- boolean canBeRemoved;
- int rightlevel;
- int removed = 0;
- int propagated = 0;
- int tested = 0;
- int l2propagation = 0;
- for (int i = 0; i < this.decisions.size(); i++) {
- d = this.decisions.get(i);
- assert !this.voc.isFalsified(toInternal(d));
- if (this.voc.isSatisfied(toInternal(d))) {
- // d has been propagated
- this.prime[Math.abs(d)] = d;
- propagated++;
- } else if (setAndPropagate(toInternal(-d))) {
- canBeRemoved = true;
- tested++;
- rightlevel = currentDecisionLevel();
- for (int j = i + 1; j < this.decisions.size(); j++) {
- l2propagation++;
- if (!setAndPropagate(toInternal(this.decisions.get(j)))) {
- canBeRemoved = false;
- break;
- }
- }
- cancelUntil(rightlevel);
- if (canBeRemoved) {
- // it is not a necessary literal
- forget(Math.abs(d));
- IConstr confl = propagate();
- assert confl == null;
- removed++;
- } else {
- this.prime[Math.abs(d)] = d;
- cancel();
- assert voc.isUnassigned(toInternal(d));
- noproblem = setAndPropagate(toInternal(d));
- assert noproblem;
- }
- } else {
- // conflict, literal is necessary
- this.prime[Math.abs(d)] = d;
- cancel();
- noproblem = setAndPropagate(toInternal(d));
- assert noproblem;
- }
- }
- cancelUntil(0);
- int[] implicant = new int[this.prime.length - removed - 1];
- int index = 0;
- for (int i : this.prime) {
- if (i != 0) {
- implicant[index++] = i;
- }
- }
- if (isVerbose()) {
- System.out.printf("%s prime implicant computation statistics%n",
- getLogPrefix());
- System.out
- .printf("%s implied: %d, decision: %d (removed %d, tested %d, propagated %d), l2 propagation:%d%n",
- getLogPrefix(), implied.size(), decisions.size(),
- removed, tested, propagated, l2propagation);
- }
- return implicant;
- }
- public boolean primeImplicant(int p) {
- if (p == 0 || Math.abs(p) > realNumberOfVariables()) {
- throw new IllegalArgumentException(
- "Use a valid Dimacs var id as argument!"); //$NON-NLS-1$
- }
- if (this.prime == null) {
- throw new UnsupportedOperationException(
- "Call the primeImplicant method first!!!"); //$NON-NLS-1$
- }
- return this.prime[Math.abs(p)] == p;
- }
- public boolean model(int var) {
- if (var <= 0 || var > realNumberOfVariables()) {
- throw new IllegalArgumentException(
- "Use a valid Dimacs var id as argument!"); //$NON-NLS-1$
- }
- if (this.userbooleanmodel == null) {
- throw new UnsupportedOperationException(
- "Call the solve method first!!!"); //$NON-NLS-1$
- }
- return this.userbooleanmodel[var - 1];
- }
- public void clearLearntClauses() {
- for (Iterator<Constr> iterator = this.learnts.iterator(); iterator
- .hasNext();) {
- iterator.next().remove(this);
- }
- this.learnts.clear();
- this.learnedLiterals.clear();
- }
- protected final void reduceDB() {
- this.stats.reduceddb++;
- this.slistener.cleaning();
- this.learnedConstraintsDeletionStrategy.reduce(this.learnts);
- System.gc();
- }
- /**
- * @param learnts
- */
- protected void sortOnActivity() {
- this.learnts.sort(this.comparator);
- }
- /**
- *
- */
- protected void decayActivities() {
- this.order.varDecayActivity();
- claDecayActivity();
- }
- /**
- *
- */
- private void claDecayActivity() {
- this.claInc *= this.claDecay;
- }
- /**
- * @return true iff the set of constraints is satisfiable, else false.
- */
- public boolean isSatisfiable() throws TimeoutException {
- return isSatisfiable(VecInt.EMPTY);
- }
- /**
- * @return true iff the set of constraints is satisfiable, else false.
- */
- public boolean isSatisfiable(boolean global) throws TimeoutException {
- return isSatisfiable(VecInt.EMPTY, global);
- }
- private double timebegin = 0;
- private boolean needToReduceDB;
- private ConflictTimerContainer conflictCount;
- private transient Timer timer;
- public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
- return isSatisfiable(assumps, false);
- }
- public final LearnedConstraintsDeletionStrategy fixedSize(final int maxsize) {
- return new LearnedConstraintsDeletionStrategy() {
- private static final long serialVersionUID = 1L;
- private final ConflictTimer aTimer = new ConflictTimerAdapter(
- maxsize) {
- private static final long serialVersionUID = 1L;
- @Override
- public void run() {
- Solver.this.needToReduceDB = true;
- }
- };
- public void reduce(IVec<Constr> learnedConstrs) {
- int i, j, k;
- for (i = j = k = 0; i < Solver.this.learnts.size()
- && Solver.this.learnts.size() - k > maxsize; i++) {
- Constr c = Solver.this.learnts.get(i);
- if (c.locked() || c.size() == 2) {
- Solver.this.learnts
- .set(j++, Solver.this.learnts.get(i));
- } else {
- c.remove(Solver.this);
- k++;
- }
- }
- for (; i < Solver.this.learnts.size(); i++) {
- Solver.this.learnts.set(j++, Solver.this.learnts.get(i));
- }
- if (Solver.this.verbose) {
- Solver.this.out.log(getLogPrefix()
- + "cleaning " + (Solver.this.learnts.size() - j) //$NON-NLS-1$
- + " clauses out of " + Solver.this.learnts.size()); //$NON-NLS-1$
- // out.flush();
- }
- Solver.this.learnts.shrinkTo(j);
- }
- public void onConflictAnalysis(Constr reason) {
- // TODO Auto-generated method stub
- }
- public void onClauseLearning(Constr outLearnt) {
- // TODO Auto-generated method stub
- }
- @Override
- public String toString() {
- return "Fixed size (" + maxsize
- + ") learned constraints deletion strategy";
- }
- public void init() {
- }
- public ConflictTimer getTimer() {
- return this.aTimer;
- }
- public void onPropagation(Constr from) {
- // TODO Auto-generated method stub
- }
- };
- }
- private LearnedConstraintsDeletionStrategy activityBased(
- final ConflictTimer timer) {
- return new LearnedConstraintsDeletionStrategy() {
- private static final long serialVersionUID = 1L;
- private final ConflictTimer freeMem = timer;
- public void reduce(IVec<Constr> learnedConstrs) {
- sortOnActivity();
- int i, j;
- for (i = j = 0; i < Solver.this.learnts.size() / 2; i++) {
- Constr c = Solver.this.learnts.get(i);
- if (c.locked() || c.size() == 2) {
- Solver.this.learnts
- .set(j++, Solver.this.learnts.get(i));
- } else {
- c.remove(Solver.this);
- }
- }
- for (; i < Solver.this.learnts.size(); i++) {
- Solver.this.learnts.set(j++, Solver.this.learnts.get(i));
- }
- if (Solver.this.verbose) {
- Solver.this.out.log(getLogPrefix()
- + "cleaning " + (Solver.this.learnts.size() - j) //$NON-NLS-1$
- + " clauses out of " + Solver.this.learnts.size()); //$NON-NLS-1$
- // out.flush();
- }
- Solver.this.learnts.shrinkTo(j);
- }
- public ConflictTimer getTimer() {
- return this.freeMem;
- }
- @Override
- public String toString() {
- return "Memory based learned constraints deletion strategy";
- }
- public void init() {
- // do nothing
- }
- public void onClauseLearning(Constr constr) {
- // do nothing
- }
- public void onConflictAnalysis(Constr reason) {
- if (reason.learnt()) {
- claBumpActivity(reason);
- }
- }
- public void onPropagation(Constr from) {
- // do nothing
- }
- };
- }
- private final ConflictTimer memoryTimer = new ConflictTimerAdapter(500) {
- private static final long serialVersionUID = 1L;
- final long memorybound = Runtime.getRuntime().freeMemory() / 10;
- @Override
- public void run() {
- long freemem = Runtime.getRuntime().freeMemory();
- // System.out.println("c Free memory "+freemem);
- if (freemem < this.memorybound) {
- // Reduce the set of learnt clauses
- Solver.this.needToReduceDB = true;
- }
- }
- };
- /**
- * @since 2.1
- */
- public final LearnedConstraintsDeletionStrategy memory_based = activityBased(this.memoryTimer);
- private class GlucoseLCDS implements LearnedConstraintsDeletionStrategy {
- private static final long serialVersionUID = 1L;
- private int[] flags = new int[0];
- private int flag = 0;
- // private int wall = 0;
- private final ConflictTimer clauseManagement;
- GlucoseLCDS(ConflictTimer timer) {
- this.clauseManagement = timer;
- }
- public void reduce(IVec<Constr> learnedConstrs) {
- sortOnActivity();
- int i, j;
- for (i = j = learnedConstrs.size() / 2; i < learnedConstrs.size(); i++) {
- Constr c = learnedConstrs.get(i);
- if (c.locked() || c.getActivity() <= 2.0) {
- learnedConstrs.set(j++, Solver.this.learnts.get(i));
- } else {
- c.remove(Solver.this);
- }
- }
- if (Solver.this.verbose) {
- Solver.this.out
- .log(getLogPrefix()
- + "cleaning " + (learnedConstrs.size() - j) //$NON-NLS-1$
- + " clauses out of " + learnedConstrs.size() + " with flag " + this.flag + "/" + Solver.this.stats.conflicts); //$NON-NLS-1$ //$NON-NLS-2$
- // out.flush();
- }
- Solver.this.learnts.shrinkTo(j);
- }
- public ConflictTimer getTimer() {
- return this.clauseManagement;
- }
- @Override
- public String toString() {
- return "Glucose learned constraints deletion strategy";
- }
- public void init() {
- final int howmany = Solver.this.voc.nVars();
- // wall = constrs.size() > 10000 ? constrs.size() : 10000;
- if (this.flags.length <= howmany) {
- this.flags = new int[howmany + 1];
- }
- this.flag = 0;
- this.clauseManagement.reset();
- }
- public void onClauseLearning(Constr constr) {
- int nblevel = computeLBD(constr);
- constr.incActivity(nblevel);
- }
- protected int computeLBD(Constr constr) {
- int nblevel = 1;
- this.flag++;
- int currentLevel;
- for (int i = 1; i < constr.size(); i++) {
- currentLevel = Solver.this.voc.getLevel(constr.get(i));
- if (this.flags[currentLevel] != this.flag) {
- this.flags[currentLevel] = this.flag;
- nblevel++;
- }
- }
- return nblevel;
- }
- public void onConflictAnalysis(Constr reason) {
- }
- public void onPropagation(Constr from) {
- }
- }
- private class Glucose2LCDS extends GlucoseLCDS {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- Glucose2LCDS(ConflictTimer timer) {
- super(timer);
- }
- @Override
- public String toString() {
- return "Glucose 2 learned constraints deletion strategy";
- }
- @Override
- public void onPropagation(Constr from) {
- if (from.getActivity() > 2.0) {
- int nblevel = computeLBD(from);
- if (nblevel < from.getActivity()) {
- Solver.this.stats.updateLBD++;
- from.setActivity(nblevel);
- }
- }
- }
- }
- private final ConflictTimer lbdTimer = new ConflictTimerAdapter(1000) {
- private static final long serialVersionUID = 1L;
- private int nbconflict = 0;
- private static final int MAX_CLAUSE = 5000;
- private static final int INC_CLAUSE = 1000;
- private int nextbound = MAX_CLAUSE;
- @Override
- public void run() {
- this.nbconflict += bound();
- if (this.nbconflict >= this.nextbound) {
- this.nextbound += INC_CLAUSE;
- // if (nextbound > wall) {
- // nextbound = wall;
- // }
- this.nbconflict = 0;
- Solver.this.needToReduceDB = true;
- }
- }
- @Override
- public void reset() {
- super.reset();
- this.nextbound = MAX_CLAUSE;
- if (this.nbconflict >= this.nextbound) {
- this.nbconflict = 0;
- Solver.this.needToReduceDB = true;
- }
- }
- };
- /**
- * @since 2.1
- */
- public final LearnedConstraintsDeletionStrategy glucose = new Glucose2LCDS(
- this.lbdTimer);
- protected LearnedConstraintsDeletionStrategy learnedConstraintsDeletionStrategy = this.glucose;
- /*
- * (non-Javadoc)
- *
- * @see
- * org.sat4j.minisat.core.ICDCL#setLearnedConstraintsDeletionStrategy(org
- * .sat4j.minisat.core.Solver.LearnedConstraintsDeletionStrategy)
- */
- public void setLearnedConstraintsDeletionStrategy(
- LearnedConstraintsDeletionStrategy lcds) {
- if (this.conflictCount != null) {
- this.conflictCount.add(lcds.getTimer());
- assert this.learnedConstraintsDeletionStrategy != null;
- this.conflictCount.remove(this.learnedConstraintsDeletionStrategy
- .getTimer());
- }
- this.learnedConstraintsDeletionStrategy = lcds;
- }
- private boolean lastConflictMeansUnsat;
- public boolean isSatisfiable(IVecInt assumps, boolean global)
- throws TimeoutException {
- Lbool status = Lbool.UNDEFINED;
- boolean alreadylaunched = this.conflictCount != null;
- final int howmany = this.voc.nVars();
- if (this.mseen.length <= howmany) {
- this.mseen = new boolean[howmany + 1];
- }
- this.trail.ensure(howmany);
- this.trailLim.ensure(howmany);
- this.learnedLiterals.ensure(howmany);
- this.decisions.clear();
- this.implied.clear();
- this.slistener.init(this);
- this.slistener.start();
- this.model = null; // forget about previous model
- this.userbooleanmodel = null;
- this.prime = null;
- this.unsatExplanationInTermsOfAssumptions = null;
- if (!alreadylaunched || !this.keepHot) {
- this.order.init();
- }
- this.learnedConstraintsDeletionStrategy.init();
- int learnedLiteralsLimit = this.trail.size();
- // Fix for Bug SAT37
- this.qhead = 0;
- // Apply undos on unit literals because they are getting propagated
- // again now that qhead is 0.
- for (int i = learnedLiteralsLimit - 1; i >= 0; i--) {
- int p = this.trail.get(i);
- IVec<Undoable> undos = this.voc.undos(p);
- assert undos != null;
- for (int size = undos.size(); size > 0; size--) {
- undos.last().undo(p);
- undos.pop();
- }
- }
- // push previously learned literals
- for (IteratorInt iterator = this.learnedLiterals.iterator(); iterator
- .hasNext();) {
- enqueue(iterator.next());
- }
- // propagate constraints
- Constr confl = propagate();
- if (confl != null) {
- analyzeAtRootLevel(confl);
- this.slistener.conflictFound(confl, 0, 0);
- this.slistener.end(Lbool.FALSE);
- cancelUntil(0);
- cancelLearntLiterals(learnedLiteralsLimit);
- return false;
- }
- // push incremental assumptions
- for (IteratorInt iterator = assumps.iterator(); iterator.hasNext();) {
- int assump = iterator.next();
- int p = this.voc.getFromPool(assump);
- if (!this.voc.isSatisfied(p) && !assume(p)
- || (confl = propagate()) != null) {
- if (confl == null) {
- this.slistener.conflictFound(p);
- this.unsatExplanationInTermsOfAssumptions = analyzeFinalConflictInTermsOfAssumptions(
- null, assumps, p);
- this.unsatExplanationInTermsOfAssumptions.push(assump);
- } else {
- this.slistener.conflictFound(confl, decisionLevel(),
- this.trail.size());
- this.unsatExplanationInTermsOfAssumptions = analyzeFinalConflictInTermsOfAssumptions(
- confl, assumps, ILits.UNDEFINED);
- }
- this.slistener.end(Lbool.FALSE);
- cancelUntil(0);
- cancelLearntLiterals(learnedLiteralsLimit);
- return false;
- }
- }
- this.rootLevel = decisionLevel();
- // moved initialization here if new literals are added in the
- // assumptions.
- if (!alreadylaunched || !this.keepHot) {
- this.order.init(); // duplicated on purpose
- }
- this.learner.init();
- if (!alreadylaunched) {
- this.conflictCount = new ConflictTimerContainer();
- this.conflictCount.add(this.restarter);
- this.conflictCount.add(this.learnedConstraintsDeletionStrategy
- .getTimer());
- }
- boolean firstTimeGlobal = false;
- if (this.timeBasedTimeout) {
- if (!global || this.timer == null) {
- firstTimeGlobal = true;
- this.undertimeout = true;
- TimerTask stopMe = new TimerTask() {
- @Override
- public void run() {
- Solver.this.undertimeout = false;
- }
- };
- this.timer = new Timer(true);
- this.timer.schedule(stopMe, this.timeout);
- }
- } else {
- if (!global || !alreadylaunched) {
- firstTimeGlobal = true;
- this.undertimeout = true;
- ConflictTimer conflictTimeout = new ConflictTimerAdapter(
- (int) this.timeout) {
- private static final long serialVersionUID = 1L;
- @Override
- public void run() {
- Solver.this.undertimeout = false;
- }
- };
- this.conflictCount.add(conflictTimeout);
- }
- }
- if (!global || firstTimeGlobal) {
- this.restarter.init(this.params, this.stats);
- this.timebegin = System.currentTimeMillis();
- }
- this.needToReduceDB = false;
- // this is used to allow the solver to be incomplete,
- // when using a heuristics limited to a subset of variables
- this.lastConflictMeansUnsat = true;
- // Solve
- while (status == Lbool.UNDEFINED && this.undertimeout
- && this.lastConflictMeansUnsat) {
- int before = this.trail.size();
- unitClauseProvider.provideUnitClauses(this);
- this.stats.importedUnits += this.trail.size() - before;
- status = search(assumps);
- if (status == Lbool.UNDEFINED) {
- this.restarter.onRestart();
- this.slistener.restarting();
- }
- }
- cancelUntil(0);
- cancelLearntLiterals(learnedLiteralsLimit);
- if (!global && this.timeBasedTimeout && this.timer != null) {
- this.timer.cancel();
- this.timer = null;
- }
- this.slistener.end(status);
- if (!this.undertimeout) {
- String message = " Timeout (" + this.timeout
- + (this.timeBasedTimeout ? "s" : " conflicts")
- + ") exceeded";
- throw new TimeoutException(message);
- }
- if (status == Lbool.UNDEFINED && !this.lastConflictMeansUnsat) {
- throw new TimeoutException("Cannot decide the satisfiability");
- }
- // When using a search enumerator (to compute all models)
- // the final answer is FALSE, however we are aware of at least one model
- // (the last one)
- return model != null;
- }
- public void printInfos(PrintWriter out) {
- printInfos(out, prefix);
- }
- public void printInfos(PrintWriter out, String prefix) {
- out.print(prefix);
- out.println("constraints type ");
- long total = 0;
- for (Map.Entry<String, Counter> entry : this.constrTypes.entrySet()) {
- out.println(prefix + entry.getKey() + " => " + entry.getValue());
- total += entry.getValue().getValue();
- }
- out.print(prefix);
- out.print(total);
- out.println(" constraints processed.");
- }
- /**
- * @since 2.1
- */
- public void printLearntClausesInfos(PrintWriter out, String prefix) {
- Map<String, Counter> learntTypes = new HashMap<String, Counter>();
- for (Iterator<Constr> it = this.learnts.iterator(); it.hasNext();) {
- String type = it.next().getClass().getName();
- Counter count = learntTypes.get(type);
- if (count == null) {
- learntTypes.put(type, new Counter());
- } else {
- count.inc();
- }
- }
- out.print(prefix);
- out.println("learnt constraints type ");
- for (Map.Entry<String, Counter> entry : learntTypes.entrySet()) {
- out.println(prefix + entry.getKey() + " => " + entry.getValue());
- }
- }
- public SolverStats getStats() {
- return this.stats;
- }
- /**
- *
- * @param myStats
- * @since 2.2
- */
- protected void initStats(SolverStats myStats) {
- this.stats = myStats;
- }
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.minisat.core.ICDCL#getOrder()
- */
- public IOrder getOrder() {
- return this.order;
- }
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.minisat.core.ICDCL#setOrder(org.sat4j.minisat.core.IOrder)
- */
- public void setOrder(IOrder h) {
- this.order = h;
- this.order.setLits(this.voc);
- }
- public ILits getVocabulary() {
- return this.voc;
- }
- public void reset() {
- if (this.timer != null) {
- this.timer.cancel();
- this.timer = null;
- }
- this.trail.clear();
- this.trailLim.clear();
- this.qhead = 0;
- for (Iterator<Constr> iterator = this.constrs.iterator(); iterator
- .hasNext();) {
- iterator.next().remove(this);
- }
- this.constrs.clear();
- clearLearntClauses();
- this.voc.resetPool();
- this.dsfactory.reset();
- this.stats.reset();
- this.constrTypes.clear();
- }
- public int nVars() {
- if (this.declaredMaxVarId == 0) {
- return this.voc.nVars();
- }
- return this.declaredMaxVarId;
- }
- /**
- * @param constr
- * a constraint implementing the Constr interface.
- * @return a reference to the constraint for external use.
- */
- protected IConstr addConstr(Constr constr) {
- if (constr == null) {
- Counter count = this.constrTypes
- .get("ignored satisfied constraints");
- if (count == null) {
- this.constrTypes.put("ignored satisfied constraints",
- new Counter());
- } else {
- count.inc();
- }
- } else {
- this.constrs.push(constr);
- String type = constr.getClass().getName();
- Counter count = this.constrTypes.get(type);
- if (count == null) {
- this.constrTypes.put(type, new Counter());
- } else {
- count.inc();
- }
- }
- return constr;
- }
- public DataStructureFactory getDSFactory() {
- return this.dsfactory;
- }
- public IVecInt getOutLearnt() {
- return this.moutLearnt;
- }
- /**
- * returns the ith constraint in the solver.
- *
- * @param i
- * the constraint number (begins at 0)
- * @return the ith constraint
- */
- public IConstr getIthConstr(int i) {
- return this.constrs.get(i);
- }
- /*
- * (non-Javadoc)
- *
- * @see org.sat4j.specs.ISolver#printStat(java.io.PrintStream,
- * java.lang.String)
- */
- public void printStat(PrintStream out, String prefix) {
- printStat(new PrintWriter(out, true), prefix);
- }
- public void printStat(PrintWriter out) {
- printStat(out, prefix);
- }
- public void printStat(PrintWriter out, String prefix) {
- this.stats.printStat(out, prefix);
- double cputime = (System.currentTimeMillis() - this.timebegin) / 1000;
- out.println(prefix
- + "speed (assignments/second)\t: " + this.stats.propagations //$NON-NLS-1$
- / cputime);
- this.order.printStat(out, prefix);
- printLearntClausesInfos(out, prefix);
- }
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#toString()
- */
- public String toString(String prefix) {
- StringBuffer stb = new StringBuffer();
- Object[] objs = { this.dsfactory, this.learner, this.params,
- this.order, this.simplifier, this.restarter,
- this.learnedConstraintsDeletionStrategy };
- stb.append(prefix);
- stb.append("--- Begin Solver configuration ---"); //$NON-NLS-1$
- stb.append("\n"); //$NON-NLS-1$
- for (Object o : objs) {
- stb.append(prefix);
- stb.append(o.toString());
- stb.append("\n"); //$NON-NLS-1$
- }
- stb.append(prefix);
- stb.append("timeout=");
- if (this.timeBasedTimeout) {
- stb.append(this.timeout / 1000);
- stb.append("s\n");
- } else {
- stb.append(this.timeout);
- stb.append(" conflicts\n");
- }
- stb.append(prefix);
- stb.append("DB Simplification allowed=");
- stb.append(this.isDBSimplificationAllowed);
- stb.append("\n");
- stb.append(prefix);
- if (isSolverKeptHot()) {
- stb.append("Heuristics kept accross calls (keep the solver \"hot\")\n");
- stb.append(prefix);
- }
- stb.append("Listener: ");
- stb.append(slistener);
- stb.append("\n");
- stb.append(prefix);
- stb.append("--- End Solver configuration ---"); //$NON-NLS-1$
- return stb.toString();
- }
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return toString(""); //$NON-NLS-1$
- }
- public int getTimeout() {
- return (int) (this.timeBasedTimeout ? this.timeout / 1000
- : this.timeout);
- }
- /**
- * @since 2.1
- */
- public long getTimeoutMs() {
- if (!this.timeBasedTimeout) {
- throw new UnsupportedOperationException(
- "The timeout is given in number of conflicts!");
- }
- return this.timeout;
- }
- public void setExpectedNumberOfClauses(int nb) {
- this.constrs.ensure(nb);
- }
- public Map<String, Number> getStat() {
- return this.stats.toMap();
- }
- public int[] findModel() throws TimeoutException {
- if (isSatisfiable()) {
- return model();
- }
- // DLB findbugs ok
- // A zero length array would mean that the formula is a tautology.
- return null;
- }
- public int[] findModel(IVecInt assumps) throws TimeoutException {
- if (isSatisfiable(assumps)) {
- return model();
- }
- // DLB findbugs ok
- // A zero length array would mean that the formula is a tautology.
- return null;
- }
- public boolean isDBSimplificationAllowed() {
- return this.isDBSimplificationAllowed;
- }
- public void setDBSimplificationAllowed(boolean status) {
- this.isDBSimplificationAllowed = status;
- }
- /**
- * @since 2.1
- */
- public int nextFreeVarId(boolean reserve) {
- return this.voc.nextFreeVarId(reserve);
- }
- /**
- * @since 2.1
- */
- public IConstr addBlockingClause(IVecInt literals)
- throws ContradictionException {
- return addClause(literals);
- }
- /**
- * @since 2.1
- */
- public void unset(int p) {
- // the literal might already have been
- // removed from the trail.
- if (this.voc.isUnassigned(p) || this.trail.isEmpty()) {
- return;
- }
- int current = this.trail.last();
- while (current != p) {
- undoOne();
- if (this.trail.isEmpty()) {
- return;
- }
- current = this.trail.last();
- }
- undoOne();
- this.qhead = this.trail.size();
- }
- /**
- * @since 2.2
- */
- public void setLogPrefix(String prefix) {
- this.prefix = prefix;
- }
- /**
- * @since 2.2
- */
- public String getLogPrefix() {
- return this.prefix;
- }
- /**
- * @since 2.2
- */
- public IVecInt unsatExplanation() {
- IVecInt copy = new VecInt(
- this.unsatExplanationInTermsOfAssumptions.size());
- this.unsatExplanationInTermsOfAssumptions.copyTo(copy);
- return copy;
- }
- /**
- * @since 2.3.1
- */
- public int[] modelWithInternalVariables() {
- if (this.model == null) {
- throw new UnsupportedOperationException(
- "Call the solve method first!!!"); //$NON-NLS-1$
- }
- int[] nmodel;
- if (nVars() == realNumberOfVariables()) {
- nmodel = new int[this.model.length];
- System.arraycopy(this.model, 0, nmodel, 0, nmodel.length);
- } else {
- nmodel = new int[this.fullmodel.length];
- System.arraycopy(this.fullmodel, 0, nmodel, 0, nmodel.length);
- }
- return nmodel;
- }
- /**
- * @since 2.3.1
- */
- public int realNumberOfVariables() {
- return this.voc.nVars();
- }
- /**
- * @since 2.3.2
- */
- public void stop() {
- expireTimeout();
- }
- protected Constr sharedConflict;
- /**
- * @since 2.3.2
- */
- public void backtrack(int[] reason) {
- IVecInt clause = new VecInt(reason.length);
- for (int d : reason) {
- clause.push(LiteralsUtils.toInternal(d));
- }
- this.sharedConflict = this.dsfactory.createUnregisteredClause(clause);
- learn(this.sharedConflict);
- }
- /**
- * @since 2.3.2
- */
- public Lbool truthValue(int literal) {
- int p = LiteralsUtils.toInternal(literal);
- if (this.voc.isFalsified(p)) {
- return Lbool.FALSE;
- }
- if (this.voc.isSatisfied(p)) {
- return Lbool.TRUE;
- }
- return Lbool.UNDEFINED;
- }
- /**
- * @since 2.3.2
- */
- public int currentDecisionLevel() {
- return decisionLevel();
- }
- /**
- * @since 2.3.2
- */
- public int[] getLiteralsPropagatedAt(int decisionLevel) {
- throw new UnsupportedOperationException("Not implemented yet!");
- }
- /**
- * @since 2.3.2
- */
- public void suggestNextLiteralToBranchOn(int l) {
- throw new UnsupportedOperationException("Not implemented yet!");
- }
- protected boolean isNeedToReduceDB() {
- return this.needToReduceDB;
- }
- public void setNeedToReduceDB(boolean needToReduceDB) {
- this.needToReduceDB = needToReduceDB;
- }
- public void setLogger(ILogAble out) {
- this.out = out;
- }
- public ILogAble getLogger() {
- return this.out;
- }
- public double[] getVariableHeuristics() {
- return this.order.getVariableHeuristics();
- }
- public IVec<Constr> getLearnedConstraints() {
- return this.learnts;
- }
- /**
- * @since 2.3.2
- */
- public void setLearnedConstraintsDeletionStrategy(ConflictTimer timer,
- LearnedConstraintsEvaluationType evaluation) {
- if (this.conflictCount != null) {
- this.conflictCount.add(timer);
- this.conflictCount.remove(this.learnedConstraintsDeletionStrategy
- .getTimer());
- }
- switch (evaluation) {
- case ACTIVITY:
- this.learnedConstraintsDeletionStrategy = activityBased(timer);
- break;
- case LBD:
- this.learnedConstraintsDeletionStrategy = new GlucoseLCDS(timer);
- break;
- case LBD2:
- this.learnedConstraintsDeletionStrategy = new Glucose2LCDS(timer);
- break;
- }
- if (this.conflictCount != null) {
- this.learnedConstraintsDeletionStrategy.init();
- }
- }
- /**
- * @since 2.3.2
- */
- public void setLearnedConstraintsDeletionStrategy(
- LearnedConstraintsEvaluationType evaluation) {
- ConflictTimer aTimer = this.learnedConstraintsDeletionStrategy
- .getTimer();
- switch (evaluation) {
- case ACTIVITY:
- this.learnedConstraintsDeletionStrategy = activityBased(aTimer);
- break;
- case LBD:
- this.learnedConstraintsDeletionStrategy = new GlucoseLCDS(aTimer);
- break;
- case LBD2:
- this.learnedConstraintsDeletionStrategy = new Glucose2LCDS(aTimer);
- break;
- }
- if (this.conflictCount != null) {
- this.learnedConstraintsDeletionStrategy.init();
- }
- }
- public boolean isSolverKeptHot() {
- return this.keepHot;
- }
- public void setKeepSolverHot(boolean keepHot) {
- this.keepHot = keepHot;
- }
- private final Comparator<Integer> dimacsLevel = new Comparator<Integer>() {
- public int compare(Integer i1, Integer i2) {
- return voc.getLevel(Math.abs(i2)) - voc.getLevel(Math.abs(i1));
- }
- };
- public IConstr addClauseOnTheFly(int[] literals) {
- List<Integer> lliterals = new ArrayList<Integer>();
- for (Integer d : literals) {
- lliterals.add(d);
- }
- Collections.sort(lliterals, dimacsLevel);
- IVecInt clause = new VecInt(literals.length);
- for (int d : lliterals) {
- clause.push(LiteralsUtils.toInternal(d));
- }
- this.sharedConflict = this.dsfactory.createUnregisteredClause(clause);
- this.sharedConflict.register();
- addConstr(this.sharedConflict);
- IVecInt reason = new VecInt();
- this.sharedConflict.calcReasonOnTheFly(ILits.UNDEFINED, trail, reason);
- Set<Integer> subset = fromLastDecisionLevel(reason);
- while (!trail.isEmpty() && !subset.contains(trail.last())) {
- undoOne();
- if (!trailLim.isEmpty() && trailLim.last() == trail.size()) {
- trailLim.pop();
- }
- }
- return this.sharedConflict;
- }
- public ISolver getSolvingEngine() {
- return this;
- }
- /**
- *
- * @param literals
- */
- public IConstr addAtMostOnTheFly(int[] literals, int degree) {
- IVecInt clause = new VecInt(literals.length);
- for (int d : literals) {
- clause.push(LiteralsUtils.toInternal(-d));
- }
- IVecInt copy = new VecInt(clause.size());
- clause.copyTo(copy);
- this.sharedConflict = this.dsfactory
- .createUnregisteredCardinalityConstraint(copy, literals.length
- - degree);
- this.sharedConflict.register();
- addConstr(this.sharedConflict);
- // backtrack to the first decision level with a reason
- // for falsifying that constraint
- IVecInt reason = new VecInt();
- this.sharedConflict.calcReasonOnTheFly(ILits.UNDEFINED, trail, reason);
- Set<Integer> subset = fromLastDecisionLevel(reason);
- while (!trail.isEmpty() && !subset.contains(trail.last())) {
- undoOne();
- if (!trailLim.isEmpty() && trailLim.last() == trail.size()) {
- trailLim.pop();
- }
- }
- return this.sharedConflict;
- }
- protected Set<Integer> fromLastDecisionLevel(IVecInt lits) {
- Set<Integer> subset = new HashSet<Integer>();
- int max = -1, q, level;
- for (int i = 0; i < lits.size(); i++) {
- q = lits.get(i);
- level = voc.getLevel(q);
- if (level > max) {
- subset.clear();
- subset.add(q);
- max = level;
- } else if (level == max) {
- subset.add(q);
- }
- }
- return subset;
- }
- public void setUnitClauseProvider(UnitClauseProvider ucp) {
- this.unitClauseProvider = ucp;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement