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.pb.constraints.pb;
29
30 import java.math.BigInteger;
31
32 import org.sat4j.core.Vec;
33 import org.sat4j.core.VecInt;
34 import org.sat4j.minisat.core.ILits;
35 import org.sat4j.minisat.core.UnitPropagationListener;
36 import org.sat4j.specs.ContradictionException;
37 import org.sat4j.specs.IVec;
38 import org.sat4j.specs.IVecInt;
39
40 public class MaxWatchPb extends WatchPb {
41
42 private static final long serialVersionUID = 1L;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 private MaxWatchPb(ILits voc, IDataStructurePB mpb) {
59
60 super(mpb);
61 this.voc = voc;
62
63 activity = 0;
64 watchCumul = BigInteger.ZERO;
65 }
66
67 private MaxWatchPb(ILits voc, int[] lits, BigInteger[] coefs, BigInteger degree) {
68
69 super(lits, coefs, degree);
70 this.voc = voc;
71
72 activity = 0;
73 watchCumul = BigInteger.ZERO;
74 }
75
76
77
78
79
80
81 @Override
82 protected void computeWatches() throws ContradictionException {
83 assert watchCumul.equals(BigInteger.ZERO);
84 for (int i = 0; i < lits.length; i++) {
85 if (voc.isFalsified(lits[i])) {
86 if (learnt){
87 voc.undos(lits[i] ^ 1).push(this);
88 voc.attach(lits[i] ^ 1, this);
89 }
90 } else {
91
92 voc.attach(lits[i] ^ 1, this);
93 watchCumul = watchCumul.add(coefs[i]);
94 }
95 }
96
97 assert watchCumul.compareTo(recalcLeftSide()) >= 0;
98 if (!learnt && watchCumul.compareTo(degree) < 0) {
99 throw new ContradictionException("non satisfiable constraint");
100 }
101 }
102
103
104
105
106
107
108 @Override
109 protected void computePropagation(UnitPropagationListener s)
110 throws ContradictionException {
111
112 int ind = 0;
113 while (ind < coefs.length
114 && watchCumul.subtract(coefs[ind]).compareTo(degree) < 0) {
115 if (voc.isUnassigned(lits[ind]) && !s.enqueue(lits[ind], this))
116 throw new ContradictionException("non satisfiable constraint");
117 ind++;
118 }
119 assert watchCumul.compareTo(recalcLeftSide()) >= 0;
120 }
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 public static MaxWatchPb maxWatchPbNew(UnitPropagationListener s,
137 ILits voc, IVecInt ps, IVecInt coefs, boolean moreThan, int degree)
138 throws ContradictionException {
139 return maxWatchPbNew(s, voc, ps, Pseudos.toVecBigInt(coefs), moreThan,
140 BigInteger.valueOf(degree));
141 }
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 public static MaxWatchPb maxWatchPbNew(UnitPropagationListener s,
158 ILits voc, IVecInt ps, IVec<BigInteger> coefs, boolean moreThan,
159 BigInteger degree) throws ContradictionException {
160
161
162 VecInt litsVec = new VecInt();
163 IVec<BigInteger> coefsVec = new Vec<BigInteger>();
164 ps.copyTo(litsVec);
165 coefs.copyTo(coefsVec);
166
167 IDataStructurePB mpb = Pseudos.niceParameters(litsVec, coefsVec, moreThan,
168 degree, voc);
169
170 if (mpb == null) {
171 return null;
172 }
173 MaxWatchPb outclause = new MaxWatchPb(voc, mpb);
174
175 if (outclause.degree.signum() <= 0)
176 return null;
177 outclause.computeWatches();
178 outclause.computePropagation(s);
179
180 return outclause;
181
182 }
183
184
185
186
187
188
189
190
191
192
193 public boolean propagate(UnitPropagationListener s, int p) {
194 voc.attach(p, this);
195
196 assert watchCumul.compareTo(recalcLeftSide()) >= 0 : "" + watchCumul
197 + "/" + recalcLeftSide() + ":" + learnt;
198
199
200 int indiceP = 0;
201 while ((lits[indiceP] ^ 1) != p)
202 indiceP++;
203
204 BigInteger coefP = coefs[indiceP];
205
206 BigInteger newcumul = watchCumul.subtract(coefP);
207 if (newcumul.compareTo(degree) < 0) {
208
209
210 assert !isSatisfiable();
211 return false;
212 }
213
214
215 voc.undos(p).push(this);
216 watchCumul = newcumul;
217
218
219 int ind = 0;
220 BigInteger limit = watchCumul.subtract(degree);
221 while (ind < coefs.length && limit.compareTo(coefs[ind]) < 0) {
222 if (voc.isUnassigned(lits[ind]) && (!s.enqueue(lits[ind], this))) {
223 assert !isSatisfiable();
224 return false;
225 }
226 ind++;
227 }
228
229 assert learnt || watchCumul.compareTo(recalcLeftSide()) >= 0;
230 assert watchCumul.compareTo(recalcLeftSide()) >= 0;
231 return true;
232 }
233
234
235
236
237 public void remove() {
238 for (int i = 0; i < lits.length; i++) {
239 if (!voc.isFalsified(lits[i]))
240 voc.attaches(lits[i] ^ 1).remove(this);
241 }
242 }
243
244
245
246
247
248
249
250 public void undo(int p) {
251 int indiceP = 0;
252 while ((lits[indiceP] ^ 1) != p)
253 indiceP++;
254
255 assert coefs[indiceP].signum() > 0;
256
257 watchCumul = watchCumul.add(coefs[indiceP]);
258 }
259
260
261
262
263 public static WatchPb watchPbNew(ILits voc, IVecInt lits, IVecInt coefs,
264 boolean moreThan, int degree) {
265 return watchPbNew(voc, lits, Pseudos.toVecBigInt(coefs), moreThan,
266 BigInteger.valueOf(degree));
267 }
268
269
270
271
272
273 public static WatchPb watchPbNew(ILits voc, IVecInt lits,
274 IVec<BigInteger> coefs, boolean moreThan, BigInteger degree) {
275 IDataStructurePB mpb = null;
276 mpb = Pseudos.niceCheckedParameters(lits, coefs, moreThan, degree, voc);
277 return new MaxWatchPb(voc, mpb);
278 }
279
280
281
282
283
284
285
286
287
288
289
290 public static MaxWatchPb normalizedMaxWatchPbNew(UnitPropagationListener s,
291 ILits voc, IDataStructurePB mpb) throws ContradictionException {
292
293 MaxWatchPb outclause = new MaxWatchPb(voc, mpb);
294
295 if (outclause.degree.signum() <= 0) {
296 return null;
297 }
298
299 outclause.computeWatches();
300
301 outclause.computePropagation(s);
302
303 return outclause;
304
305 }
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321 public static MaxWatchPb normalizedMaxWatchPbNew(UnitPropagationListener s,
322 ILits voc, int[] lits, BigInteger[] coefs, BigInteger degree) throws ContradictionException {
323
324 MaxWatchPb outclause = new MaxWatchPb(voc, lits, coefs, degree);
325
326 if (outclause.degree.signum() <= 0) {
327 return null;
328 }
329
330 outclause.computeWatches();
331
332 outclause.computePropagation(s);
333
334 return outclause;
335
336 }
337
338
339
340
341 public static WatchPb normalizedWatchPbNew(ILits voc, IDataStructurePB mpb) {
342 return new MaxWatchPb(voc, mpb);
343 }
344
345
346 }