1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| |
16 |
| |
17 |
| |
18 |
| |
19 |
| |
20 |
| |
21 |
| |
22 |
| |
23 |
| |
24 |
| |
25 |
| |
26 |
| package org.sat4j.minisat.constraints.pb; |
27 |
| |
28 |
| import java.io.Serializable; |
29 |
| import java.math.BigInteger; |
30 |
| |
31 |
| import org.sat4j.core.Vec; |
32 |
| import org.sat4j.core.VecInt; |
33 |
| import org.sat4j.minisat.core.ILits; |
34 |
| import org.sat4j.minisat.core.UnitPropagationListener; |
35 |
| import org.sat4j.specs.ContradictionException; |
36 |
| import org.sat4j.specs.IVec; |
37 |
| import org.sat4j.specs.IVecInt; |
38 |
| |
39 |
| public class MinWatchPb extends WatchPb implements Serializable { |
40 |
| |
41 |
| private static final long serialVersionUID = 1L; |
42 |
| |
43 |
| |
44 |
| |
45 |
| |
46 |
| private boolean[] watched; |
47 |
| |
48 |
| |
49 |
| |
50 |
| |
51 |
| private int[] watching; |
52 |
| |
53 |
| |
54 |
| |
55 |
| |
56 |
| private int watchingCount = 0; |
57 |
| |
58 |
| |
59 |
| |
60 |
| |
61 |
| |
62 |
| |
63 |
| |
64 |
| |
65 |
| |
66 |
| |
67 |
| |
68 |
| |
69 |
| |
70 |
| |
71 |
| |
72 |
812835
| private MinWatchPb(ILits voc, IVecInt ps, IVec<BigInteger> bigCoefs,
|
73 |
| boolean moreThan, BigInteger bigDeg) { |
74 |
| |
75 |
812835
| super(ps, bigCoefs, moreThan, bigDeg);
|
76 |
812835
| this.voc = voc;
|
77 |
| |
78 |
812835
| watching = new int[this.coefs.length];
|
79 |
812835
| watched = new boolean[this.coefs.length];
|
80 |
812835
| activity = 0;
|
81 |
812835
| watchCumul = BigInteger.ZERO;
|
82 |
812835
| locked = false;
|
83 |
812835
| undos = new VecInt();
|
84 |
| |
85 |
812835
| watchingCount = 0;
|
86 |
| |
87 |
| } |
88 |
| |
89 |
| |
90 |
| |
91 |
| |
92 |
| |
93 |
| |
94 |
812747
| @Override
|
95 |
| protected void computeWatches() throws ContradictionException { |
96 |
| assert watchCumul.signum() == 0; |
97 |
| assert watchingCount == 0; |
98 |
812747
| for (int i = 0; i < lits.length
|
99 |
| && watchCumul.subtract(coefs[0]).compareTo(degree) < 0; i++) { |
100 |
2796412
| if (!voc.isFalsified(lits[i])) {
|
101 |
1877399
| voc.watch(lits[i] ^ 1, this);
|
102 |
1877399
| watching[watchingCount++] = i;
|
103 |
1877399
| watched[i] = true;
|
104 |
| |
105 |
1877399
| watchCumul = watchCumul.add(coefs[i]);
|
106 |
| } |
107 |
| } |
108 |
| |
109 |
812747
| if (learnt) {
|
110 |
| |
111 |
| |
112 |
33138
| int free = 1;
|
113 |
| |
114 |
33138
| while ((watchCumul.subtract(coefs[0]).compareTo(degree) < 0)
|
115 |
| && (free > 0)) { |
116 |
33207
| free = 0;
|
117 |
| |
118 |
33207
| int maxlevel = -1, maxi = -1;
|
119 |
33207
| for (int i = 0; i < lits.length; i++) {
|
120 |
| |
121 |
1091356
| if (voc.isFalsified(lits[i]) && !watched[i]) {
|
122 |
934766
| free++;
|
123 |
934766
| int level = voc.getLevel(lits[i]);
|
124 |
934766
| if (level > maxlevel) {
|
125 |
75381
| maxi = i;
|
126 |
75381
| maxlevel = level;
|
127 |
| } |
128 |
| } |
129 |
| |
130 |
| } |
131 |
33207
| if (free > 0) {
|
132 |
| assert maxi >= 0; |
133 |
33193
| voc.watch(lits[maxi] ^ 1, this);
|
134 |
33193
| watching[watchingCount++] = maxi;
|
135 |
33193
| watched[maxi] = true;
|
136 |
| |
137 |
33193
| watchCumul = watchCumul.add(coefs[maxi]);
|
138 |
33193
| free--;
|
139 |
| assert free >= 0; |
140 |
| } |
141 |
| } |
142 |
| assert lits.length == 1 || watchingCount > 1; |
143 |
| } |
144 |
| |
145 |
812747
| if (watchCumul.compareTo(degree) < 0) {
|
146 |
17
| throw new ContradictionException("non satisfiable constraint");
|
147 |
| } |
148 |
| assert nbOfWatched() == watchingCount; |
149 |
| } |
150 |
| |
151 |
| |
152 |
| |
153 |
| |
154 |
| |
155 |
| |
156 |
779592
| @Override
|
157 |
| protected void computePropagation(UnitPropagationListener s) |
158 |
| throws ContradictionException { |
159 |
| |
160 |
779592
| int ind = 0;
|
161 |
779592
| while (ind < lits.length
|
162 |
| && watchCumul.subtract(coefs[watching[ind]]).compareTo(degree) < 0) { |
163 |
266
| if (voc.isUnassigned(lits[ind])) {
|
164 |
212
| if (!s.enqueue(lits[ind], this)) {
|
165 |
0
| throw new ContradictionException(
|
166 |
| "non satisfiable constraint"); |
167 |
| } |
168 |
| } |
169 |
266
| ind++;
|
170 |
| } |
171 |
| } |
172 |
| |
173 |
| |
174 |
| |
175 |
| |
176 |
| |
177 |
| |
178 |
| |
179 |
| |
180 |
| |
181 |
| |
182 |
| |
183 |
| |
184 |
| |
185 |
| |
186 |
| |
187 |
499336
| public static MinWatchPb minWatchPbNew(UnitPropagationListener s,
|
188 |
| ILits voc, IVecInt ps, IVecInt coefs, boolean moreThan, int degree) |
189 |
| throws ContradictionException { |
190 |
499336
| return minWatchPbNew(s, voc, ps, toVecBigInt(coefs), moreThan,
|
191 |
| toBigInt(degree)); |
192 |
| } |
193 |
| |
194 |
| |
195 |
| |
196 |
| |
197 |
| |
198 |
| |
199 |
| |
200 |
| |
201 |
| |
202 |
| |
203 |
| |
204 |
| |
205 |
| |
206 |
| |
207 |
| |
208 |
779609
| public static MinWatchPb minWatchPbNew(UnitPropagationListener s,
|
209 |
| ILits voc, IVecInt ps, IVec<BigInteger> coefs, boolean moreThan, |
210 |
| BigInteger degree) throws ContradictionException { |
211 |
| |
212 |
779609
| VecInt litsVec = new VecInt(ps.size());
|
213 |
779609
| IVec<BigInteger> coefsVec = new Vec<BigInteger>(coefs.size());
|
214 |
779609
| ps.copyTo(litsVec);
|
215 |
779609
| coefs.copyTo(coefsVec);
|
216 |
| |
217 |
| |
218 |
779609
| niceParameter(litsVec, coefsVec);
|
219 |
779609
| MinWatchPb outclause = new MinWatchPb(voc, litsVec, coefsVec, moreThan,
|
220 |
| degree); |
221 |
| |
222 |
779609
| if (outclause.degree.signum() <= 0) {
|
223 |
0
| return null;
|
224 |
| } |
225 |
| |
226 |
779609
| outclause.computeWatches();
|
227 |
| |
228 |
779592
| outclause.computePropagation(s);
|
229 |
| |
230 |
779592
| return outclause;
|
231 |
| |
232 |
| } |
233 |
| |
234 |
| |
235 |
| |
236 |
| |
237 |
| |
238 |
| |
239 |
474473165
| protected int nbOfWatched() {
|
240 |
474473165
| int retour = 0;
|
241 |
474473165
| for (int ind = 0; ind < this.watched.length; ind++) {
|
242 |
1325056923
| for (int i = 0; i < watchingCount; i++)
|
243 |
| if (watching[i] == ind) |
244 |
| assert watched[ind]; |
245 |
1325056923
| retour += (this.watched[ind]) ? 1 : 0;
|
246 |
| } |
247 |
474473165
| return retour;
|
248 |
| } |
249 |
| |
250 |
| |
251 |
| |
252 |
| |
253 |
| |
254 |
| |
255 |
| |
256 |
| |
257 |
| |
258 |
| |
259 |
115955700
| public boolean propagate(UnitPropagationListener s, int p) {
|
260 |
| assert nbOfWatched() == watchingCount; |
261 |
| |
262 |
| assert watchingCount > 1; |
263 |
| |
264 |
115955700
| int pIndiceWatching = 0;
|
265 |
115955700
| while (pIndiceWatching < watchingCount
|
266 |
| && (lits[watching[pIndiceWatching]] ^ 1) != p) |
267 |
197692266
| pIndiceWatching++;
|
268 |
115955700
| int pIndice = watching[pIndiceWatching];
|
269 |
| |
270 |
| assert p == (lits[pIndice] ^ 1); |
271 |
| assert watched[pIndice]; |
272 |
| |
273 |
| |
274 |
| |
275 |
115955700
| BigInteger maxCoef = BigInteger.ZERO;
|
276 |
115955700
| int maxIndice = 0;
|
277 |
115955700
| for (int i = 0; i < watchingCount; i++)
|
278 |
432872455
| if (coefs[watching[i]].compareTo(maxCoef) > 0
|
279 |
| && watching[i] != pIndice) { |
280 |
116315933
| maxCoef = coefs[watching[i]];
|
281 |
116315933
| maxIndice = 0;
|
282 |
| } |
283 |
| |
284 |
| assert learnt || maxCoef.signum() != 0; |
285 |
| |
286 |
| |
287 |
| |
288 |
115955700
| int ind;
|
289 |
115955700
| if (watchingCount >= size())
|
290 |
35387453
| ind = lits.length;
|
291 |
| else { |
292 |
80568247
| ind = 0;
|
293 |
80568247
| while (ind < lits.length
|
294 |
| && watchCumul.subtract(coefs[pIndice]).subtract(maxCoef) |
295 |
| .compareTo(degree) < 0) { |
296 |
735091195
| if (!voc.isFalsified(lits[ind]) && !watched[ind]) {
|
297 |
45778841
| watchCumul = watchCumul.add(coefs[ind]);
|
298 |
45778841
| watched[ind] = true;
|
299 |
| assert watchingCount < size(); |
300 |
45778841
| watching[watchingCount++] = ind;
|
301 |
45778841
| voc.watch(lits[ind] ^ 1, this);
|
302 |
| |
303 |
45778841
| if (coefs[ind].compareTo(maxCoef) > 0)
|
304 |
8579
| maxCoef = coefs[ind];
|
305 |
| } |
306 |
735091195
| ind++;
|
307 |
| } |
308 |
| } |
309 |
| assert nbOfWatched() == watchingCount; |
310 |
| |
311 |
| |
312 |
115955700
| if (watchCumul.subtract(coefs[pIndice]).compareTo(degree) < 0) {
|
313 |
0
| voc.watch(p, this);
|
314 |
| assert watched[pIndice]; |
315 |
| assert !isSatisfiable(); |
316 |
0
| return false;
|
317 |
115955700
| } else if (ind >= lits.length) {
|
318 |
| |
319 |
| assert watchingCount != 0; |
320 |
70644646
| for (int i = 0; i < watchingCount; i++) {
|
321 |
301999338
| if (watchCumul.subtract(coefs[pIndice]).subtract(
|
322 |
| coefs[watching[i]]).compareTo(degree) < 0 |
323 |
| && i != pIndiceWatching) { |
324 |
222127548
| if (!voc.isSatisfied(lits[watching[i]])&&!s.enqueue(lits[watching[i]], this)) {
|
325 |
5169654
| voc.watch(p, this);
|
326 |
| assert !isSatisfiable(); |
327 |
5169654
| return false;
|
328 |
| } |
329 |
| } |
330 |
| } |
331 |
| |
332 |
65474992
| voc.undos(p).push(this);
|
333 |
| } |
334 |
| |
335 |
| |
336 |
110786046
| watched[pIndice] = false;
|
337 |
110786046
| watchCumul = watchCumul.subtract(coefs[pIndice]);
|
338 |
110786046
| watching[pIndiceWatching] = watching[--watchingCount];
|
339 |
| |
340 |
| assert watchingCount != 0; |
341 |
| assert nbOfWatched() == watchingCount; |
342 |
| |
343 |
110786046
| return true;
|
344 |
| } |
345 |
| |
346 |
| |
347 |
| |
348 |
| |
349 |
34623
| public void remove() {
|
350 |
34623
| for (int i = 0; i < watchingCount; i++) {
|
351 |
70119
| voc.watches(lits[watching[i]] ^ 1).remove(this);
|
352 |
70119
| this.watched[this.watching[i]] = false;
|
353 |
| } |
354 |
34623
| watchingCount = 0;
|
355 |
| assert nbOfWatched() == watchingCount; |
356 |
| } |
357 |
| |
358 |
| |
359 |
| |
360 |
| |
361 |
| |
362 |
| |
363 |
| |
364 |
65464183
| public void undo(int p) {
|
365 |
65464183
| voc.watch(p, this);
|
366 |
65464183
| int pIndice = 0;
|
367 |
65464183
| while ((lits[pIndice] ^ 1) != p)
|
368 |
278043138
| pIndice++;
|
369 |
| |
370 |
| assert pIndice < lits.length; |
371 |
| |
372 |
65464183
| watchCumul = watchCumul.add(coefs[pIndice]);
|
373 |
| |
374 |
| assert watchingCount == nbOfWatched(); |
375 |
| |
376 |
65464183
| watched[pIndice] = true;
|
377 |
65464183
| watching[watchingCount++] = pIndice;
|
378 |
| |
379 |
| assert watchingCount == nbOfWatched(); |
380 |
| } |
381 |
| |
382 |
| |
383 |
| |
384 |
| |
385 |
0
| public static WatchPb watchPbNew(ILits voc, IVecInt lits, IVecInt coefs,
|
386 |
| boolean moreThan, int degree) { |
387 |
0
| return new MinWatchPb(voc, lits, toVecBigInt(coefs), moreThan,
|
388 |
| toBigInt(degree)); |
389 |
| } |
390 |
| |
391 |
| |
392 |
| |
393 |
| |
394 |
33226
| public static WatchPb watchPbNew(ILits voc, IVecInt lits,
|
395 |
| IVec<BigInteger> coefs, boolean moreThan, BigInteger degree) { |
396 |
33226
| return new MinWatchPb(voc, lits, coefs, moreThan, degree);
|
397 |
| } |
398 |
| } |