View Javadoc

1   /*******************************************************************************
2    * SAT4J: a SATisfiability library for Java Copyright (C) 2004-2008 Daniel Le Berre
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the Eclipse Public License v1.0
6    * which accompanies this distribution, and is available at
7    * http://www.eclipse.org/legal/epl-v10.html
8    *
9    * Alternatively, the contents of this file may be used under the terms of
10   * either the GNU Lesser General Public License Version 2.1 or later (the
11   * "LGPL"), in which case the provisions of the LGPL are applicable instead
12   * of those above. If you wish to allow use of your version of this file only
13   * under the terms of the LGPL, and not to allow others to use your version of
14   * this file under the terms of the EPL, indicate your decision by deleting
15   * the provisions above and replace them with the notice and other provisions
16   * required by the LGPL. If you do not delete the provisions above, a recipient
17   * may use your version of this file under the terms of the EPL or the LGPL.
18   * 
19   * Based on the original MiniSat specification from:
20   * 
21   * An extensible SAT solver. Niklas Een and Niklas Sorensson. Proceedings of the
22   * Sixth International Conference on Theory and Applications of Satisfiability
23   * Testing, LNCS 2919, pp 502-518, 2003.
24   *
25   * See www.minisat.se for the original solver in C++.
26   * 
27   *******************************************************************************/
28  package org.sat4j.minisat.constraints.cnf;
29  
30  import java.io.Serializable;
31  
32  import org.sat4j.minisat.core.Constr;
33  import org.sat4j.minisat.core.ILits;
34  import org.sat4j.minisat.core.Undoable;
35  import org.sat4j.minisat.core.UnitPropagationListener;
36  import org.sat4j.specs.IVecInt;
37  
38  /**
39   * @author leberre
40   * @since 2.1
41   */
42  public class CBClause implements Constr, Undoable, Serializable {
43  
44  	private static final long serialVersionUID = 1L;
45  
46  	protected int falsified;
47  
48  	private boolean learnt;
49  
50  	protected final int[] lits;
51  
52  	protected final ILits voc;
53  
54  	private double activity;
55  
56  	public static CBClause brandNewClause(UnitPropagationListener s, ILits voc,
57  			IVecInt literals) {
58  		CBClause c = new CBClause(literals, voc);
59  		c.register();
60  		return c;
61  	}
62  
63  	/**
64       * 
65       */
66  	public CBClause(IVecInt ps, ILits voc, boolean learnt) {
67  		this.learnt = learnt;
68  		this.lits = new int[ps.size()];
69  		this.voc = voc;
70  		ps.moveTo(this.lits);
71  	}
72  
73  	public CBClause(IVecInt ps, ILits voc) {
74  		this(ps, voc, false);
75  	}
76  
77  	/**
78  	 * @since 2.1
79  	 */
80  	public void remove(UnitPropagationListener upl) {
81  		for (int i = 0; i < lits.length; i++) {
82  			voc.watches(lits[i] ^ 1).remove(this);
83  		}
84  	}
85  
86  	/*
87  	 * (non-Javadoc)
88  	 * 
89  	 * @seeorg.sat4j.minisat.core.Constr#propagate(org.sat4j.minisat.core.
90  	 * UnitPropagationListener, int)
91  	 */
92  	public boolean propagate(UnitPropagationListener s, int p) {
93  		voc.undos(p).push(this);
94  		falsified++;
95  		assert falsified != lits.length;
96  		if (falsified == lits.length - 1) {
97  			// find unassigned literal
98  			for (int i = 0; i < lits.length; i++) {
99  				if (!voc.isFalsified(lits[i])) {
100 					return s.enqueue(lits[i], this);
101 				}
102 			}
103 			// one of the variable in to be propagated to false.
104 			// (which explains why the falsified counter has not
105 			// been increased yet)
106 			return false;
107 		}
108 		return true;
109 	}
110 
111 	/*
112 	 * (non-Javadoc)
113 	 * 
114 	 * @see org.sat4j.minisat.core.Constr#simplify()
115 	 */
116 	public boolean simplify() {
117 		for (int p : lits) {
118 			if (voc.isSatisfied(p)) {
119 				return true;
120 			}
121 		}
122 		return false;
123 	}
124 
125 	/*
126 	 * (non-Javadoc)
127 	 * 
128 	 * @see org.sat4j.minisat.core.Constr#undo(int)
129 	 */
130 	public void undo(int p) {
131 		falsified--;
132 	}
133 
134 	/*
135 	 * (non-Javadoc)
136 	 * 
137 	 * @see org.sat4j.minisat.core.Constr#calcReason(int,
138 	 * org.sat4j.specs.VecInt)
139 	 */
140 	public void calcReason(int p, IVecInt outReason) {
141 		assert outReason.size() == 0;
142 		for (int q : lits) {
143 			assert voc.isFalsified(q) || q == p;
144 			if (voc.isFalsified(q)) {
145 				outReason.push(q ^ 1);
146 			}
147 		}
148 		assert (p == ILits.UNDEFINED) || (outReason.size() == lits.length - 1);
149 	}
150 
151 	/*
152 	 * (non-Javadoc)
153 	 * 
154 	 * @see org.sat4j.minisat.core.Constr#learnt()
155 	 */
156 	public boolean learnt() {
157 		return learnt;
158 	}
159 
160 	/*
161 	 * (non-Javadoc)
162 	 * 
163 	 * @see org.sat4j.minisat.core.Constr#incActivity(double)
164 	 */
165 	public void incActivity(double claInc) {
166 		if (learnt) {
167 			activity += claInc;
168 		}
169 	}
170 
171 	/*
172 	 * (non-Javadoc)
173 	 * 
174 	 * @see org.sat4j.minisat.core.Constr#getActivity()
175 	 */
176 	public double getActivity() {
177 		return activity;
178 	}
179 
180 	/*
181 	 * (non-Javadoc)
182 	 * 
183 	 * @see org.sat4j.minisat.core.Constr#locked()
184 	 */
185 	public boolean locked() {
186 		return voc.getReason(lits[0]) == this;
187 	}
188 
189 	/*
190 	 * (non-Javadoc)
191 	 * 
192 	 * @see org.sat4j.minisat.core.Constr#setLearnt()
193 	 */
194 	public void setLearnt() {
195 		learnt = true;
196 	}
197 
198 	/*
199 	 * (non-Javadoc)
200 	 * 
201 	 * @see org.sat4j.minisat.core.Constr#register()
202 	 */
203 	public void register() {
204 		for (int p : lits) {
205 			voc.watch(p ^ 1, this);
206 		}
207 		if (learnt) {
208 			for (int p : lits) {
209 				if (voc.isFalsified(p)) {
210 					voc.undos(p ^ 1).push(this);
211 					falsified++;
212 				}
213 			}
214 			assert falsified == lits.length - 1;
215 		}
216 	}
217 
218 	/*
219 	 * (non-Javadoc)
220 	 * 
221 	 * @see org.sat4j.minisat.core.Constr#rescaleBy(double)
222 	 */
223 	public void rescaleBy(double d) {
224 		activity *= d;
225 	}
226 
227 	/*
228 	 * (non-Javadoc)
229 	 * 
230 	 * @see org.sat4j.minisat.core.Constr#size()
231 	 */
232 	public int size() {
233 		return lits.length;
234 	}
235 
236 	/*
237 	 * (non-Javadoc)
238 	 * 
239 	 * @see org.sat4j.minisat.core.Constr#get(int)
240 	 */
241 	public int get(int i) {
242 		return lits[i];
243 	}
244 
245 	/*
246 	 * (non-Javadoc)
247 	 * 
248 	 * @see
249 	 * org.sat4j.minisat.core.Constr#assertConstraint(org.sat4j.minisat.core
250 	 * .UnitPropagationListener)
251 	 */
252 	public void assertConstraint(UnitPropagationListener s) {
253 		assert voc.isUnassigned(lits[0]);
254 		boolean ret = s.enqueue(lits[0], this);
255 		assert ret;
256 	}
257 
258 	@Override
259 	public String toString() {
260 		StringBuffer stb = new StringBuffer();
261 		for (int i = 0; i < lits.length; i++) {
262 			stb.append(lits[i]);
263 			stb.append("["); //$NON-NLS-1$
264 			stb.append(voc.valueToString(lits[i]));
265 			stb.append("]"); //$NON-NLS-1$
266 			stb.append(" "); //$NON-NLS-1$
267 		}
268 		return stb.toString();
269 	}
270 
271 	/**
272 	 * @since 2.1
273 	 */
274 	public void forwardActivity(double claInc) {
275 		if (!learnt) {
276 			activity += claInc;
277 		}
278 	}
279 }