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
27
28
29
30 package org.sat4j.minisat.constraints.card;
31
32 import java.io.Serializable;
33 import java.math.BigInteger;
34
35 import org.sat4j.minisat.constraints.cnf.Lits;
36 import org.sat4j.minisat.constraints.cnf.UnitClauses;
37 import org.sat4j.minisat.core.Constr;
38 import org.sat4j.minisat.core.ILits;
39 import org.sat4j.minisat.core.Propagatable;
40 import org.sat4j.minisat.core.Undoable;
41 import org.sat4j.minisat.core.UnitPropagationListener;
42 import org.sat4j.specs.ContradictionException;
43 import org.sat4j.specs.IVecInt;
44
45 public final class MaxWatchCard implements Propagatable, Constr, Undoable,
46 Serializable {
47
48 private static final long serialVersionUID = 1L;
49
50
51
52
53 private int degree;
54
55
56
57
58 private final int[] lits;
59
60
61
62
63 private boolean moreThan;
64
65
66
67
68 private int watchCumul;
69
70
71
72
73 private final ILits voc;
74
75
76
77
78
79
80
81
82
83 private MaxWatchCard(ILits voc, IVecInt ps, boolean moreThan, int degree) {
84
85
86 this.voc = voc;
87 this.degree = degree;
88 this.moreThan = moreThan;
89
90
91 int[] index = new int[voc.nVars() * 2 + 2];
92 for (int i = 0; i < index.length; i++) {
93 index[i] = 0;
94 }
95
96 for (int i = 0; i < ps.size(); i++) {
97 if (index[ps.get(i) ^ 1] == 0) {
98 index[ps.get(i)]++;
99 } else {
100 index[ps.get(i) ^ 1]--;
101 }
102 }
103
104 int ind = 0;
105 while (ind < ps.size()) {
106 if (index[ps.get(ind)] > 0) {
107 index[ps.get(ind)]--;
108 ind++;
109 } else {
110 if ((ps.get(ind) & 1) != 0) {
111 this.degree--;
112 }
113 ps.set(ind, ps.last());
114 ps.pop();
115 }
116 }
117
118
119 this.lits = new int[ps.size()];
120 ps.moveTo(this.lits);
121
122
123 normalize();
124
125
126 this.watchCumul = 0;
127
128
129 for (int i = 0; i < this.lits.length; i++) {
130
131 if (!voc.isFalsified(this.lits[i])) {
132 this.watchCumul++;
133 voc.watch(this.lits[i] ^ 1, this);
134 }
135 }
136 }
137
138
139
140
141
142
143
144
145
146
147 public void calcReason(int p, IVecInt outReason) {
148 for (int lit : this.lits) {
149 if (this.voc.isFalsified(lit)) {
150 outReason.push(lit ^ 1);
151 }
152 }
153 }
154
155
156
157
158
159
160
161 public double getActivity() {
162
163 return 0;
164 }
165
166
167
168
169
170
171
172
173 public void incActivity(double claInc) {
174
175 }
176
177 public void setActivity(double d) {
178 }
179
180
181
182
183
184
185
186 public boolean learnt() {
187
188 return false;
189 }
190
191
192
193
194
195
196
197 public boolean locked() {
198
199 return true;
200 }
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 public static Constr maxWatchCardNew(UnitPropagationListener s, ILits voc,
219 IVecInt ps, boolean moreThan, int degree)
220 throws ContradictionException {
221
222 MaxWatchCard outclause = null;
223
224
225 if (ps.size() < degree) {
226 throw new ContradictionException(
227 "Creating trivially inconsistent constraint");
228 } else if (ps.size() == degree) {
229 for (int i = 0; i < ps.size(); i++) {
230 if (!s.enqueue(ps.get(i))) {
231 throw new ContradictionException(
232 "Contradiction with implied literal");
233 }
234 }
235 return new UnitClauses(ps);
236 }
237
238
239 outclause = new MaxWatchCard(voc, ps, moreThan, degree);
240
241
242 if (outclause.degree <= 0) {
243 return null;
244 }
245
246
247 if (outclause.watchCumul < outclause.degree) {
248 throw new ContradictionException();
249 }
250
251
252 if (outclause.watchCumul == outclause.degree) {
253 for (int i = 0; i < outclause.lits.length; i++) {
254 if (!s.enqueue(outclause.lits[i])) {
255 throw new ContradictionException(
256 "Contradiction with implied literal");
257 }
258 }
259 return null;
260 }
261
262 return outclause;
263 }
264
265
266
267
268 public final void normalize() {
269
270 if (!this.moreThan) {
271
272 this.degree = 0 - this.degree;
273
274 for (int indLit = 0; indLit < this.lits.length; indLit++) {
275 this.lits[indLit] = this.lits[indLit] ^ 1;
276 this.degree++;
277 }
278 this.moreThan = true;
279 }
280 }
281
282
283
284
285
286
287
288
289
290
291 public boolean propagate(UnitPropagationListener s, int p) {
292
293
294 this.voc.watch(p, this);
295 assert !this.voc.isFalsified(p);
296
297
298 if (this.watchCumul == this.degree) {
299 return false;
300 }
301
302
303 this.voc.undos(p).push(this);
304 this.watchCumul--;
305
306
307 if (this.watchCumul == this.degree) {
308 for (int q : this.lits) {
309 if (this.voc.isUnassigned(q) && !s.enqueue(q, this)) {
310 return false;
311 }
312 }
313 }
314 return true;
315 }
316
317
318
319
320 public void remove(UnitPropagationListener upl) {
321 for (int q : this.lits) {
322 this.voc.watches(q ^ 1).remove(this);
323 }
324 }
325
326
327
328
329
330
331
332 public void rescaleBy(double d) {
333 }
334
335
336
337
338
339
340 public boolean simplify() {
341
342 int i = 0;
343
344
345 int curr = this.watchCumul;
346
347
348 while (i < this.lits.length) {
349
350 if (this.voc.isUnassigned(this.lits[i++])) {
351 curr--;
352 if (curr < this.degree) {
353 return false;
354 }
355 }
356 }
357
358 return false;
359 }
360
361
362
363
364
365
366 @Override
367 public String toString() {
368 StringBuffer stb = new StringBuffer();
369
370 if (this.lits.length > 0) {
371 if (this.voc.isUnassigned(this.lits[0])) {
372 stb.append(Lits.toString(this.lits[0]));
373 stb.append(" ");
374 }
375 for (int i = 1; i < this.lits.length; i++) {
376 if (this.voc.isUnassigned(this.lits[i])) {
377 stb.append(" + ");
378 stb.append(Lits.toString(this.lits[i]));
379 stb.append(" ");
380 }
381 }
382 stb.append(">= ");
383 stb.append(this.degree);
384 }
385 return stb.toString();
386 }
387
388
389
390
391
392
393
394 public void undo(int p) {
395 this.watchCumul++;
396 }
397
398 public void setLearnt() {
399 throw new UnsupportedOperationException();
400 }
401
402 public void register() {
403 throw new UnsupportedOperationException();
404 }
405
406 public int size() {
407 return this.lits.length;
408 }
409
410 public int get(int i) {
411 return this.lits[i];
412 }
413
414 public void assertConstraint(UnitPropagationListener s) {
415 throw new UnsupportedOperationException();
416 }
417
418
419
420
421
422
423 public BigInteger getCoef(int literal) {
424 return BigInteger.ONE;
425 }
426
427
428
429
430
431
432 public BigInteger getDegree() {
433 return BigInteger.valueOf(this.degree);
434 }
435
436 public ILits getVocabulary() {
437 return this.voc;
438 }
439
440
441
442
443 public void forwardActivity(double claInc) {
444
445
446 }
447
448 public boolean canBePropagatedMultipleTimes() {
449 return true;
450 }
451
452 public Constr toConstraint() {
453 return this;
454 }
455 }