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 import java.util.HashMap;
32 import java.util.Map;
33
34 import org.sat4j.minisat.core.ILits;
35 import org.sat4j.minisat.core.UnitPropagationListener;
36 import org.sat4j.specs.ContradictionException;
37
38
39
40
41
42
43
44
45
46 public final class MaxWatchPbLong extends WatchPbLong {
47
48 private static final long serialVersionUID = 1L;
49
50
51
52
53 private long watchCumul = 0;
54
55 private final Map<Integer, Long> litToCoeffs;
56
57
58
59
60
61
62
63
64
65
66
67
68
69 private MaxWatchPbLong(ILits voc, IDataStructurePB mpb) {
70
71 super(mpb);
72 this.voc = voc;
73
74 activity = 0;
75 watchCumul = 0;
76 if (coefs.length > MaxWatchPb.LIMIT_FOR_MAP) {
77 litToCoeffs = new HashMap<Integer, Long>(coefs.length);
78 for (int i = 0; i < coefs.length; i++) {
79 litToCoeffs.put(lits[i], coefs[i]);
80 }
81 } else
82 litToCoeffs = null;
83 }
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 private MaxWatchPbLong(ILits voc, int[] lits, BigInteger[] coefs,
99 BigInteger degree) {
100
101 super(lits, coefs, degree);
102 this.voc = voc;
103
104 activity = 0;
105 watchCumul = 0;
106 if (coefs.length > MaxWatchPb.LIMIT_FOR_MAP) {
107 litToCoeffs = new HashMap<Integer, Long>(coefs.length);
108 for (int i = 0; i < coefs.length; i++) {
109 litToCoeffs.put(lits[i], this.coefs[i]);
110 }
111 } else
112 litToCoeffs = null;
113 }
114
115
116
117
118
119
120 @Override
121 protected void computeWatches() throws ContradictionException {
122 assert watchCumul == 0;
123 for (int i = 0; i < lits.length; i++) {
124 if (voc.isFalsified(lits[i])) {
125 if (learnt) {
126 voc.undos(lits[i] ^ 1).push(this);
127 voc.watch(lits[i] ^ 1, this);
128 }
129 } else {
130
131 voc.watch(lits[i] ^ 1, this);
132 watchCumul = watchCumul + coefs[i];
133 }
134 }
135
136 assert watchCumul >= computeLeftSide();
137 if (!learnt && watchCumul < degree) {
138 throw new ContradictionException("non satisfiable constraint");
139 }
140 }
141
142
143
144
145
146
147
148
149 @Override
150 protected void computePropagation(UnitPropagationListener s)
151 throws ContradictionException {
152
153 int ind = 0;
154 while (ind < coefs.length && (watchCumul - coefs[ind]) < degree) {
155 if (voc.isUnassigned(lits[ind]) && !s.enqueue(lits[ind], this))
156
157 throw new ContradictionException("non satisfiable constraint");
158 ind++;
159 }
160 assert watchCumul >= computeLeftSide();
161 }
162
163
164
165
166
167
168
169
170
171
172 @Override
173 public boolean propagate(UnitPropagationListener s, int p) {
174 voc.watch(p, this);
175
176 assert watchCumul >= computeLeftSide() : "" + watchCumul + "/"
177 + computeLeftSide() + ":" + learnt;
178
179
180 long coefP;
181 if (litToCoeffs == null) {
182
183 int indiceP = 0;
184 while ((lits[indiceP] ^ 1) != p)
185 indiceP++;
186
187
188 coefP = coefs[indiceP];
189 } else {
190 coefP = litToCoeffs.get(p ^ 1);
191 }
192 long newcumul = watchCumul - coefP;
193
194 if (newcumul < degree) {
195
196 assert !isSatisfiable();
197 return false;
198 }
199
200
201
202 voc.undos(p).push(this);
203
204 watchCumul = newcumul;
205
206
207 int ind = 0;
208
209
210
211 long limit = watchCumul - degree;
212
213 while (ind < coefs.length && limit < coefs[ind]) {
214
215 if (voc.isUnassigned(lits[ind]) && (!s.enqueue(lits[ind], this))) {
216
217 assert !isSatisfiable();
218 return false;
219 }
220 ind++;
221 }
222
223 assert learnt || watchCumul >= computeLeftSide();
224 assert watchCumul >= computeLeftSide();
225 return true;
226 }
227
228
229
230
231 @Override
232 public void remove(UnitPropagationListener upl) {
233 for (int i = 0; i < lits.length; i++) {
234 if (!voc.isFalsified(lits[i])) {
235 voc.watches(lits[i] ^ 1).remove(this);
236 }
237 if (voc.isSatisfied(lits[i])) {
238
239 upl.unset(lits[i]);
240 }
241 }
242 }
243
244
245
246
247
248
249
250 @Override
251 public void undo(int p) {
252 long coefP;
253 if (litToCoeffs == null) {
254
255 int indiceP = 0;
256 while ((lits[indiceP] ^ 1) != p)
257 indiceP++;
258
259
260 coefP = coefs[indiceP];
261 } else {
262 coefP = litToCoeffs.get(p ^ 1);
263 }
264 watchCumul = watchCumul + coefP;
265 }
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285 public static MaxWatchPbLong normalizedMaxWatchPbNew(
286 UnitPropagationListener s, ILits voc, int[] lits,
287 BigInteger[] coefs, BigInteger degree)
288 throws ContradictionException {
289
290 MaxWatchPbLong outclause = new MaxWatchPbLong(voc, lits, coefs, degree);
291
292 if (outclause.degree <= 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 public static WatchPbLong normalizedWatchPbNew(ILits voc,
318 IDataStructurePB mpb) {
319 return new MaxWatchPbLong(voc, mpb);
320 }
321
322 }