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