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.minisat.core.ILits;
33 import org.sat4j.minisat.core.UnitPropagationListener;
34 import org.sat4j.specs.ContradictionException;
35
36 public class MaxWatchPb extends WatchPb {
37
38 private static final long serialVersionUID = 1L;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 private MaxWatchPb(ILits voc, IDataStructurePB mpb) {
55
56 super(mpb);
57 this.voc = voc;
58
59 activity = 0;
60 watchCumul = BigInteger.ZERO;
61 }
62
63 private MaxWatchPb(ILits voc, int[] lits, BigInteger[] coefs,
64 BigInteger degree) {
65
66 super(lits, coefs, degree);
67 this.voc = voc;
68
69 activity = 0;
70 watchCumul = BigInteger.ZERO;
71 }
72
73
74
75
76
77
78 @Override
79 protected void computeWatches() throws ContradictionException {
80 assert watchCumul.equals(BigInteger.ZERO);
81 for (int i = 0; i < lits.length; i++) {
82 if (voc.isFalsified(lits[i])) {
83 if (learnt) {
84 voc.undos(lits[i] ^ 1).push(this);
85 voc.watch(lits[i] ^ 1, this);
86 }
87 } else {
88
89 voc.watch(lits[i] ^ 1, this);
90 watchCumul = watchCumul.add(coefs[i]);
91 }
92 }
93
94 assert watchCumul.compareTo(recalcLeftSide()) >= 0;
95 if (!learnt && watchCumul.compareTo(degree) < 0) {
96 throw new ContradictionException("non satisfiable constraint");
97 }
98 }
99
100
101
102
103
104
105 @Override
106 protected void computePropagation(UnitPropagationListener s)
107 throws ContradictionException {
108
109 int ind = 0;
110 while (ind < coefs.length
111 && watchCumul.subtract(coefs[ind]).compareTo(degree) < 0) {
112 if (voc.isUnassigned(lits[ind]) && !s.enqueue(lits[ind], this))
113 throw new ContradictionException("non satisfiable constraint");
114 ind++;
115 }
116 assert watchCumul.compareTo(recalcLeftSide()) >= 0;
117 }
118
119
120
121
122
123
124
125
126
127
128 public boolean propagate(UnitPropagationListener s, int p) {
129 voc.watch(p, this);
130
131 assert watchCumul.compareTo(recalcLeftSide()) >= 0 : "" + watchCumul
132 + "/" + recalcLeftSide() + ":" + learnt;
133
134
135 int indiceP = 0;
136 while ((lits[indiceP] ^ 1) != p)
137 indiceP++;
138
139 BigInteger coefP = coefs[indiceP];
140
141 BigInteger newcumul = watchCumul.subtract(coefP);
142 if (newcumul.compareTo(degree) < 0) {
143
144
145 assert !isSatisfiable();
146 return false;
147 }
148
149
150 voc.undos(p).push(this);
151 watchCumul = newcumul;
152
153
154 int ind = 0;
155 BigInteger limit = watchCumul.subtract(degree);
156 while (ind < coefs.length && limit.compareTo(coefs[ind]) < 0) {
157 if (voc.isUnassigned(lits[ind]) && (!s.enqueue(lits[ind], this))) {
158 assert !isSatisfiable();
159 return false;
160 }
161 ind++;
162 }
163
164 assert learnt || watchCumul.compareTo(recalcLeftSide()) >= 0;
165 assert watchCumul.compareTo(recalcLeftSide()) >= 0;
166 return true;
167 }
168
169
170
171
172 public void remove(UnitPropagationListener upl) {
173 for (int i = 0; i < lits.length; i++) {
174 if (!voc.isFalsified(lits[i]))
175 voc.watches(lits[i] ^ 1).remove(this);
176 }
177 }
178
179
180
181
182
183
184
185 public void undo(int p) {
186 int indiceP = 0;
187 while ((lits[indiceP] ^ 1) != p)
188 indiceP++;
189
190 assert coefs[indiceP].signum() > 0;
191
192 watchCumul = watchCumul.add(coefs[indiceP]);
193 }
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209 public static MaxWatchPb normalizedMaxWatchPbNew(UnitPropagationListener s,
210 ILits voc, int[] lits, BigInteger[] coefs, BigInteger degree)
211 throws ContradictionException {
212
213 MaxWatchPb outclause = new MaxWatchPb(voc, lits, coefs, degree);
214
215 if (outclause.degree.signum() <= 0) {
216 return null;
217 }
218
219 outclause.computeWatches();
220
221 outclause.computePropagation(s);
222
223 return outclause;
224
225 }
226
227
228
229
230 public static WatchPb normalizedWatchPbNew(ILits voc, IDataStructurePB mpb) {
231 return new MaxWatchPb(voc, mpb);
232 }
233
234 }