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