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 final 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 for (int i = 0; i < lits.length; i++) {
142 if (voc.isFalsified(lits[i])) {
143 outReason.push(lits[i] ^ 1);
144 }
145 }
146 }
147
148
149
150
151
152
153
154 public double getActivity() {
155
156 return 0;
157 }
158
159
160
161
162
163
164
165
166 public void incActivity(double claInc) {
167
168 }
169
170
171
172
173
174
175
176 public boolean learnt() {
177
178 return false;
179 }
180
181
182
183
184
185
186
187 public boolean locked() {
188
189 return true;
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208 public static MaxWatchCard maxWatchCardNew(UnitPropagationListener s,
209 ILits voc, IVecInt ps, boolean moreThan, int degree)
210 throws ContradictionException {
211
212 MaxWatchCard outclause = null;
213
214
215 if (ps.size() == 0) {
216 throw new ContradictionException("Creating empty clause");
217 } else if (ps.size() == degree) {
218 for (int i = 0; i < ps.size(); i++)
219 if (!s.enqueue(ps.get(i))) {
220 throw new ContradictionException(
221 "Contradiction with implied literal");
222 }
223 return null;
224 }
225
226
227 outclause = new MaxWatchCard(voc, ps, moreThan, degree);
228
229
230 if (outclause.degree <= 0)
231 return null;
232
233
234 if (outclause.watchCumul < outclause.degree)
235 throw new ContradictionException();
236
237
238 if (outclause.watchCumul == outclause.degree) {
239 for (int i = 0; i < outclause.lits.length; i++) {
240 if (!s.enqueue(outclause.lits[i])) {
241 throw new ContradictionException(
242 "Contradiction with implied literal");
243 }
244 }
245 return null;
246 }
247
248 return outclause;
249 }
250
251
252
253
254 public final void normalize() {
255
256 if (!moreThan) {
257
258 this.degree = 0 - this.degree;
259
260 for (int indLit = 0; indLit < lits.length; indLit++) {
261 lits[indLit] = lits[indLit] ^ 1;
262 this.degree++;
263 }
264 this.moreThan = true;
265 }
266 }
267
268
269
270
271
272
273
274
275
276
277 public boolean propagate(UnitPropagationListener s, int p) {
278
279
280 voc.watch(p, this);
281 assert !voc.isFalsified(p);
282
283
284 if (this.watchCumul == this.degree)
285 return false;
286
287
288 voc.undos(p).push(this);
289 watchCumul--;
290
291
292 if (watchCumul == degree) {
293 for (int q : lits) {
294 if (voc.isUnassigned(q) && !s.enqueue(q, this)) {
295 return false;
296 }
297 }
298 }
299 return true;
300 }
301
302
303
304
305 public void remove(UnitPropagationListener upl) {
306 for (int q : lits) {
307 voc.watches(q ^ 1).remove(this);
308 }
309 }
310
311
312
313
314
315
316
317 public void rescaleBy(double d) {
318 }
319
320
321
322
323
324
325 public boolean simplify() {
326
327 int i = 0;
328
329
330 int curr = watchCumul;
331
332
333 while (i < this.lits.length) {
334
335 if (voc.isUnassigned(lits[i++])) {
336 curr--;
337 if (curr < this.degree)
338 return false;
339 }
340 }
341
342 return false;
343 }
344
345
346
347
348
349
350 @Override
351 public String toString() {
352 StringBuffer stb = new StringBuffer();
353
354 if (lits.length > 0) {
355 if (voc.isUnassigned(lits[0])) {
356 stb.append(Lits.toString(this.lits[0]));
357 stb.append(" ");
358 }
359 for (int i = 1; i < lits.length; i++) {
360 if (voc.isUnassigned(lits[i])) {
361 stb.append(" + ");
362 stb.append(Lits.toString(this.lits[i]));
363 stb.append(" ");
364 }
365 }
366 stb.append(">= ");
367 stb.append(this.degree);
368 }
369 return stb.toString();
370 }
371
372
373
374
375
376
377
378 public void undo(int p) {
379 watchCumul++;
380 }
381
382 public void setLearnt() {
383 throw new UnsupportedOperationException();
384 }
385
386 public void register() {
387 throw new UnsupportedOperationException();
388 }
389
390 public int size() {
391 return lits.length;
392 }
393
394 public int get(int i) {
395 return lits[i];
396 }
397
398 public void assertConstraint(UnitPropagationListener s) {
399 throw new UnsupportedOperationException();
400 }
401
402
403
404
405
406
407 public BigInteger getCoef(int literal) {
408 return BigInteger.ONE;
409 }
410
411
412
413
414
415
416 public BigInteger getDegree() {
417 return BigInteger.valueOf(degree);
418 }
419
420 public ILits getVocabulary() {
421 return voc;
422 }
423
424
425
426
427 public void forwardActivity(double claInc) {
428
429
430 }
431
432 }