/******************************************************************************* * 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. * * 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++. * *******************************************************************************/ package org.sat4j.minisat.constraints.cnf; import java.io.Serializable; import org.sat4j.core.Vec; import org.sat4j.minisat.core.Constr; import org.sat4j.minisat.core.ILits; import org.sat4j.minisat.core.Propagatable; import org.sat4j.minisat.core.Undoable; import org.sat4j.specs.IVec; /** * @author laihem * @author leberre * */ public class Lits implements Serializable, ILits { private static final long serialVersionUID = 1L; private boolean pool[] = new boolean[1]; private int realnVars = 0; @SuppressWarnings("unchecked") protected IVec<Propagatable>[] watches = new IVec[0]; private int[] level = new int[0]; private Constr[] reason = new Constr[0]; private int maxvarid = 0; @SuppressWarnings("unchecked") private IVec<Undoable>[] undos = new IVec[0]; private boolean[] falsified = new boolean[0]; public Lits() { init(128); } @SuppressWarnings( { "unchecked" }) public void init(int nvar) { if (nvar < pool.length) return; assert nvar >= 0; // let some space for unused 0 indexer. int nvars = nvar + 1; boolean[] npool = new boolean[nvars]; System.arraycopy(pool, 0, npool, 0, pool.length); pool = npool; int[] nlevel = new int[nvars]; System.arraycopy(level, 0, nlevel, 0, level.length); level = nlevel; IVec<Propagatable>[] nwatches = new IVec[2 * nvars]; System.arraycopy(watches, 0, nwatches, 0, watches.length); watches = nwatches; IVec<Undoable>[] nundos = new IVec[nvars]; System.arraycopy(undos, 0, nundos, 0, undos.length); undos = nundos; Constr[] nreason = new Constr[nvars]; System.arraycopy(reason, 0, nreason, 0, reason.length); reason = nreason; boolean[] newFalsified = new boolean[2 * nvars]; System.arraycopy(falsified, 0, newFalsified, 0, falsified.length); falsified = newFalsified; } public int getFromPool(int x) { int var = Math.abs(x); if (var >= pool.length) { init(Math.max(var, pool.length << 1)); } assert var < pool.length; if (var > maxvarid) { maxvarid = var; } int lit = ((x < 0) ? (var << 1) ^ 1 : (var << 1)); assert lit > 1; if (!pool[var]) { realnVars++; pool[var] = true; watches[var << 1] = new Vec<Propagatable>(); watches[(var << 1) | 1] = new Vec<Propagatable>(); undos[var] = new Vec<Undoable>(); level[var] = -1; falsified[var << 1] = false; // because truthValue[var] is // UNDEFINED falsified[var << 1 | 1] = false; // because truthValue[var] is // UNDEFINED } return lit; } public boolean belongsToPool(int x) { assert x > 0; if (x >= pool.length) return false; return pool[x]; } public void resetPool() { for (int i = 0; i < pool.length; i++) { if (pool[i]) { reset(i << 1); } } } public void ensurePool(int howmany) { if (howmany >= pool.length) init(howmany); maxvarid = howmany; } public void unassign(int lit) { assert falsified[lit] || falsified[lit ^ 1]; falsified[lit] = false; falsified[lit ^ 1] = false; } public void satisfies(int lit) { assert !falsified[lit] && !falsified[lit ^ 1]; falsified[lit] = false; falsified[lit ^ 1] = true; } public boolean isSatisfied(int lit) { return falsified[lit ^ 1]; } public final boolean isFalsified(int lit) { return falsified[lit]; } public boolean isUnassigned(int lit) { return !falsified[lit] && !falsified[lit ^ 1]; } public String valueToString(int lit) { if (isUnassigned(lit)) return "?"; //$NON-NLS-1$ if (isSatisfied(lit)) return "T"; //$NON-NLS-1$ return "F"; //$NON-NLS-1$ } public int nVars() { // return pool.length - 1; return maxvarid; } public int not(int lit) { return lit ^ 1; } public static String toString(int lit) { return ((lit & 1) == 0 ? "" : "-") + (lit >> 1); //$NON-NLS-1$//$NON-NLS-2$ } public void reset(int lit) { watches[lit].clear(); watches[lit ^ 1].clear(); level[lit >> 1] = -1; reason[lit >> 1] = null; undos[lit >> 1].clear(); falsified[lit] = false; falsified[lit ^ 1] = false; } public int getLevel(int lit) { return level[lit >> 1]; } public void setLevel(int lit, int l) { level[lit >> 1] = l; } public Constr getReason(int lit) { return reason[lit >> 1]; } public void setReason(int lit, Constr r) { reason[lit >> 1] = r; } public IVec<Undoable> undos(int lit) { return undos[lit >> 1]; } public void attach(int lit, Propagatable c) { watches[lit].push(c); } public IVec<Propagatable> attaches(int lit) { return watches[lit]; } public boolean isImplied(int lit) { int var = lit >> 1; assert reason[var] == null || falsified[lit] || falsified[lit ^ 1]; // a literal is implied if it is a unit clause, ie // propagated without reason at decision level 0. return pool[var] && (reason[var] != null || level[var] == 0); } public int realnVars() { return realnVars; } /** * To get the capacity of the current vocabulary. * * @return the total number of variables that can be managed by the * vocabulary. */ protected int capacity() { return pool.length - 1; } }