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.card;
29  
30  import java.io.Serializable;
31  
32  import org.sat4j.minisat.constraints.cnf.Lits;
33  import org.sat4j.minisat.constraints.cnf.UnitClauses;
34  import org.sat4j.minisat.core.Constr;
35  import org.sat4j.minisat.core.ILits;
36  import org.sat4j.minisat.core.Undoable;
37  import org.sat4j.minisat.core.UnitPropagationListener;
38  import org.sat4j.specs.ContradictionException;
39  import org.sat4j.specs.IVecInt;
40  
41  /**
42   * @author leberre Contrainte de cardinalit?
43   */
44  public class AtLeast implements Constr, Undoable, Serializable {
45  
46  	private static final long serialVersionUID = 1L;
47  
48  	/** number of allowed falsified literal */
49  	protected int maxUnsatisfied;
50  
51  	/** current number of falsified literals */
52  	private int counter;
53  
54  	/**
55  	 * constraint literals
56  	 */
57  	protected final int[] lits;
58  
59  	protected final ILits voc;
60  
61  	/**
62  	 * @param ps
63  	 *            a vector of literals
64  	 * @param degree
65  	 *            the minimal number of satisfied literals
66  	 */
67  	protected AtLeast(ILits voc, IVecInt ps, int degree) {
68  		maxUnsatisfied = ps.size() - degree;
69  		this.voc = voc;
70  		counter = 0;
71  		lits = new int[ps.size()];
72  		ps.moveTo(lits);
73  		for (int q : lits) {
74  			voc.watch(q ^ 1, this);
75  		}
76  	}
77  
78  	protected static int niceParameters(UnitPropagationListener s, ILits voc,
79  			IVecInt ps, int deg) throws ContradictionException {
80  
81  		if (ps.size() < deg)
82  			throw new ContradictionException();
83  		int degree = deg;
84  		for (int i = 0; i < ps.size();) {
85  			// on verifie si le litteral est affecte
86  			if (voc.isUnassigned(ps.get(i))) {
87  				// go to next literal
88  				i++;
89  			} else {
90  				// Si le litteral est satisfait,
91  				// ?a revient ? baisser le degr?
92  				if (voc.isSatisfied(ps.get(i))) {
93  					degree--;
94  				}
95  				// dans tous les cas, s'il est assign?,
96  				// on enleve le ieme litteral
97  				ps.delete(i);
98  			}
99  		}
100 
101 		// on trie le vecteur ps
102 		ps.sortUnique();
103 		// ?limine les clauses tautologiques
104 		// deux litt?raux de signe oppos?s apparaissent dans la m?me
105 		// clause
106 
107 		if (ps.size() == degree) {
108 			for (int i = 0; i < ps.size(); i++) {
109 				if (!s.enqueue(ps.get(i))) {
110 					throw new ContradictionException();
111 				}
112 			}
113 			return 0;
114 		}
115 
116 		if (ps.size() < degree)
117 			throw new ContradictionException();
118 		return degree;
119 
120 	}
121 
122 	/**
123 	 * @since 2.1
124 	 */
125 	public static Constr atLeastNew(UnitPropagationListener s, ILits voc,
126 			IVecInt ps, int n) throws ContradictionException {
127 		int degree = niceParameters(s, voc, ps, n);
128 		if (degree == 0)
129 			return new UnitClauses(ps);
130 		return new AtLeast(voc, ps, degree);
131 	}
132 
133 	/**
134 	 * @since 2.1
135 	 */
136 	public void remove(UnitPropagationListener upl) {
137 		for (int q : lits) {
138 			voc.watches(q ^ 1).remove(this);
139 		}
140 	}
141 
142 	/*
143 	 * (non-Javadoc)
144 	 * 
145 	 * @see Constr#propagate(Solver, Lit)
146 	 */
147 	public boolean propagate(UnitPropagationListener s, int p) {
148 		// remet la clause dans la liste des clauses regardees
149 		voc.watch(p, this);
150 
151 		if (counter == maxUnsatisfied)
152 			return false;
153 
154 		counter++;
155 		voc.undos(p).push(this);
156 
157 		// If no more can be false, enqueue the rest:
158 		if (counter == maxUnsatisfied)
159 			for (int q : lits) {
160 				if (voc.isUnassigned(q) && !s.enqueue(q, this)) {
161 					return false;
162 				}
163 			}
164 		return true;
165 	}
166 
167 	/*
168 	 * (non-Javadoc)
169 	 * 
170 	 * @see Constr#simplify(Solver)
171 	 */
172 	public boolean simplify() {
173 		return false;
174 	}
175 
176 	/*
177 	 * (non-Javadoc)
178 	 * 
179 	 * @see Constr#undo(Solver, Lit)
180 	 */
181 	public void undo(int p) {
182 		counter--;
183 	}
184 
185 	/*
186 	 * (non-Javadoc)
187 	 * 
188 	 * @see Constr#calcReason(Solver, Lit, Vec)
189 	 */
190 	public void calcReason(int p, IVecInt outReason) {
191 		int c = (p == ILits.UNDEFINED) ? -1 : 0;
192 		for (int q : lits) {
193 			if (voc.isFalsified(q)) {
194 				outReason.push(q ^ 1);
195 				if (++c == maxUnsatisfied)
196 					return;
197 			}
198 		}
199 	}
200 
201 	/*
202 	 * (non-Javadoc)
203 	 * 
204 	 * @see org.sat4j.minisat.datatype.Constr#learnt()
205 	 */
206 	public boolean learnt() {
207 		// Ces contraintes ne sont pas apprises pour le moment.
208 		return false;
209 	}
210 
211 	/*
212 	 * (non-Javadoc)
213 	 * 
214 	 * @see org.sat4j.minisat.datatype.Constr#getActivity()
215 	 */
216 	public double getActivity() {
217 		// TODO Auto-generated method stub
218 		return 0;
219 	}
220 
221 	/*
222 	 * (non-Javadoc)
223 	 * 
224 	 * @see org.sat4j.minisat.datatype.Constr#incActivity(double)
225 	 */
226 	public void incActivity(double claInc) {
227 		// TODO Auto-generated method stub
228 
229 	}
230 
231 	/*
232 	 * For learnt clauses only @author leberre
233 	 */
234 	public boolean locked() {
235 		// FIXME need to be adapted to AtLeast
236 		// return lits[0].getReason() == this;
237 		return true;
238 	}
239 
240 	public void setLearnt() {
241 		throw new UnsupportedOperationException();
242 	}
243 
244 	public void register() {
245 		throw new UnsupportedOperationException();
246 	}
247 
248 	public int size() {
249 		return lits.length;
250 	}
251 
252 	public int get(int i) {
253 		return lits[i];
254 	}
255 
256 	public void rescaleBy(double d) {
257 		throw new UnsupportedOperationException();
258 	}
259 
260 	public void assertConstraint(UnitPropagationListener s) {
261 		throw new UnsupportedOperationException();
262 	}
263 
264 	/**
265 	 * Cha?ne repr?sentant la contrainte
266 	 * 
267 	 * @return Cha?ne repr?sentant la contrainte
268 	 */
269 	@Override
270 	public String toString() {
271 		StringBuffer stb = new StringBuffer();
272 		stb.append("Card (" + lits.length + ") : ");
273 		for (int i = 0; i < lits.length; i++) {
274 			// if (voc.isUnassigned(lits[i])) {
275 			stb.append(" + "); //$NON-NLS-1$
276 			stb.append(Lits.toString(this.lits[i]));
277 			stb.append("[");
278 			stb.append(voc.valueToString(lits[i]));
279 			stb.append("@");
280 			stb.append(voc.getLevel(lits[i]));
281 			stb.append("]");
282 			stb.append(" ");
283 			stb.append(" "); //$NON-NLS-1$
284 		}
285 		stb.append(">= "); //$NON-NLS-1$
286 		stb.append(size() - maxUnsatisfied);
287 
288 		return stb.toString();
289 	}
290 
291 	/**
292 	 * @since 2.1
293 	 */
294 	public void forwardActivity(double claInc) {
295 		// TODO Auto-generated method stub
296 
297 	}
298 
299 }