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 pseudo boolean algorithms described in:
20   * A fast pseudo-Boolean constraint solver Chai, D.; Kuehlmann, A.
21   * Computer-Aided Design of Integrated Circuits and Systems, IEEE Transactions on
22   * Volume 24, Issue 3, March 2005 Page(s): 305 - 317
23   * 
24   * and 
25   * Heidi E. Dixon, 2004. Automating Pseudo-Boolean Inference within a DPLL 
26   * Framework. Ph.D. Dissertation, University of Oregon.
27   *******************************************************************************/
28  package org.sat4j.pb.constraints.pb;
29  
30  import java.math.BigInteger;
31  
32  import org.sat4j.minisat.core.ILits;
33  import org.sat4j.minisat.core.UnitPropagationListener;
34  import org.sat4j.specs.ContradictionException;
35  
36  public class MaxWatchPb extends WatchPb {
37  
38  	private static final long serialVersionUID = 1L;
39  
40  	/**
41  	 * Constructeur de base cr?ant des contraintes vides
42  	 * 
43  	 * @param voc
44  	 *            Informations sur le vocabulaire employ?
45  	 * @param ps
46  	 *            Liste des litt?raux
47  	 * @param weightedLits
48  	 *            Liste des coefficients
49  	 * @param moreThan
50  	 *            Indication sur le comparateur
51  	 * @param degree
52  	 *            Stockage du degr? de la contrainte
53  	 */
54  	private MaxWatchPb(ILits voc, IDataStructurePB mpb) {
55  
56  		super(mpb);
57  		this.voc = voc;
58  
59  		activity = 0;
60  		watchCumul = BigInteger.ZERO;
61  	}
62  
63  	private MaxWatchPb(ILits voc, int[] lits, BigInteger[] coefs,
64  			BigInteger degree) {
65  
66  		super(lits, coefs, degree);
67  		this.voc = voc;
68  
69  		activity = 0;
70  		watchCumul = BigInteger.ZERO;
71  	}
72  
73  	/**
74  	 * Permet l'observation de tous les litt???raux
75  	 * 
76  	 * @see org.sat4j.pb.constraints.pb.WatchPb#computeWatches()
77  	 */
78  	@Override
79  	protected void computeWatches() throws ContradictionException {
80  		assert watchCumul.equals(BigInteger.ZERO);
81  		for (int i = 0; i < lits.length; i++) {
82  			if (voc.isFalsified(lits[i])) {
83  				if (learnt) {
84  					voc.undos(lits[i] ^ 1).push(this);
85  					voc.watch(lits[i] ^ 1, this);
86  				}
87  			} else {
88  				// Mise ? jour de la possibilit? initiale
89  				voc.watch(lits[i] ^ 1, this);
90  				watchCumul = watchCumul.add(coefs[i]);
91  			}
92  		}
93  
94  		assert watchCumul.compareTo(recalcLeftSide()) >= 0;
95  		if (!learnt && watchCumul.compareTo(degree) < 0) {
96  			throw new ContradictionException("non satisfiable constraint");
97  		}
98  	}
99  
100 	/*
101 	 * (non-Javadoc)
102 	 * 
103 	 * @see org.sat4j.minisat.constraints.WatchPb#computePropagation()
104 	 */
105 	@Override
106 	protected void computePropagation(UnitPropagationListener s)
107 			throws ContradictionException {
108 		// On propage
109 		int ind = 0;
110 		while (ind < coefs.length
111 				&& watchCumul.subtract(coefs[ind]).compareTo(degree) < 0) {
112 			if (voc.isUnassigned(lits[ind]) && !s.enqueue(lits[ind], this))
113 				throw new ContradictionException("non satisfiable constraint");
114 			ind++;
115 		}
116 		assert watchCumul.compareTo(recalcLeftSide()) >= 0;
117 	}
118 
119 	/**
120 	 * Propagation de la valeur de v?rit? d'un litt?ral falsifi?
121 	 * 
122 	 * @param s
123 	 *            un prouveur
124 	 * @param p
125 	 *            le litt?ral propag? (il doit etre falsifie)
126 	 * @return false ssi une inconsistance est d?tect?e
127 	 */
128 	public boolean propagate(UnitPropagationListener s, int p) {
129 		voc.watch(p, this);
130 
131 		assert watchCumul.compareTo(recalcLeftSide()) >= 0 : "" + watchCumul
132 				+ "/" + recalcLeftSide() + ":" + learnt;
133 
134 		// Si le litt?ral est impliqu? il y a un conflit
135 		int indiceP = 0;
136 		while ((lits[indiceP] ^ 1) != p)
137 			indiceP++;
138 
139 		BigInteger coefP = coefs[indiceP];
140 
141 		BigInteger newcumul = watchCumul.subtract(coefP);
142 		if (newcumul.compareTo(degree) < 0) {
143 			// System.out.println(this.analyse(new ConstrHandle()));
144 
145 			assert !isSatisfiable();
146 			return false;
147 		}
148 
149 		// On met en place la mise ? jour du compteur
150 		voc.undos(p).push(this);
151 		watchCumul = newcumul;
152 
153 		// On propage
154 		int ind = 0;
155 		BigInteger limit = watchCumul.subtract(degree);
156 		while (ind < coefs.length && limit.compareTo(coefs[ind]) < 0) {
157 			if (voc.isUnassigned(lits[ind]) && (!s.enqueue(lits[ind], this))) {
158 				assert !isSatisfiable();
159 				return false;
160 			}
161 			ind++;
162 		}
163 
164 		assert learnt || watchCumul.compareTo(recalcLeftSide()) >= 0;
165 		assert watchCumul.compareTo(recalcLeftSide()) >= 0;
166 		return true;
167 	}
168 
169 	/**
170 	 * Enl???ve une contrainte du prouveur
171 	 */
172 	public void remove(UnitPropagationListener upl) {
173 		for (int i = 0; i < lits.length; i++) {
174 			if (!voc.isFalsified(lits[i]))
175 				voc.watches(lits[i] ^ 1).remove(this);
176 		}
177 	}
178 
179 	/**
180 	 * M?thode appel?e lors du backtrack
181 	 * 
182 	 * @param p
183 	 *            un litt?ral d?saffect?
184 	 */
185 	public void undo(int p) {
186 		int indiceP = 0;
187 		while ((lits[indiceP] ^ 1) != p)
188 			indiceP++;
189 
190 		assert coefs[indiceP].signum() > 0;
191 
192 		watchCumul = watchCumul.add(coefs[indiceP]);
193 	}
194 
195 	/**
196 	 * @param s
197 	 *            a unit propagation listener
198 	 * @param voc
199 	 *            the vocabulary
200 	 * @param lits
201 	 *            the literals of the constraint
202 	 * @param coefs
203 	 *            the coefficients of the constraint
204 	 * @param degree
205 	 *            the degree of the constraint
206 	 * @return a new PB constraint or null if a trivial inconsistency is
207 	 *         detected.
208 	 */
209 	public static MaxWatchPb normalizedMaxWatchPbNew(UnitPropagationListener s,
210 			ILits voc, int[] lits, BigInteger[] coefs, BigInteger degree)
211 			throws ContradictionException {
212 		// Il ne faut pas modifier les param?tres
213 		MaxWatchPb outclause = new MaxWatchPb(voc, lits, coefs, degree);
214 
215 		if (outclause.degree.signum() <= 0) {
216 			return null;
217 		}
218 
219 		outclause.computeWatches();
220 
221 		outclause.computePropagation(s);
222 
223 		return outclause;
224 
225 	}
226 
227 	/**
228      * 
229      */
230 	public static WatchPb normalizedWatchPbNew(ILits voc, IDataStructurePB mpb) {
231 		return new MaxWatchPb(voc, mpb);
232 	}
233 
234 }