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
32 import org.sat4j.minisat.constraints.cnf.Lits;
33 import org.sat4j.minisat.constraints.cnf.UnitClauses;
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
42
43
44 public class AtLeast implements Constr, Undoable, Serializable {
45
46 private static final long serialVersionUID = 1L;
47
48
49 protected int maxUnsatisfied;
50
51
52 private int counter;
53
54
55
56
57 protected final int[] lits;
58
59 protected final ILits voc;
60
61
62
63
64
65
66
67 protected AtLeast(ILits voc, IVecInt ps, int degree) {
68 maxUnsatisfied = ps.size() - degree;
69 this.voc = voc;
70 counter = 0;
71 lits = new int[ps.size()];
72 ps.moveTo(lits);
73 for (int q : lits) {
74 voc.watch(q ^ 1, this);
75 }
76 }
77
78 protected static int niceParameters(UnitPropagationListener s, ILits voc,
79 IVecInt ps, int deg) throws ContradictionException {
80
81 if (ps.size() < deg)
82 throw new ContradictionException();
83 int degree = deg;
84 for (int i = 0; i < ps.size();) {
85
86 if (voc.isUnassigned(ps.get(i))) {
87
88 i++;
89 } else {
90
91
92 if (voc.isSatisfied(ps.get(i))) {
93 degree--;
94 }
95
96
97 ps.delete(i);
98 }
99 }
100
101
102 ps.sortUnique();
103
104
105
106
107 if (ps.size() == degree) {
108 for (int i = 0; i < ps.size(); i++) {
109 if (!s.enqueue(ps.get(i))) {
110 throw new ContradictionException();
111 }
112 }
113 return 0;
114 }
115
116 if (ps.size() < degree)
117 throw new ContradictionException();
118 return degree;
119
120 }
121
122
123
124
125 public static Constr atLeastNew(UnitPropagationListener s, ILits voc,
126 IVecInt ps, int n) throws ContradictionException {
127 int degree = niceParameters(s, voc, ps, n);
128 if (degree == 0)
129 return new UnitClauses(ps);
130 return new AtLeast(voc, ps, degree);
131 }
132
133
134
135
136 public void remove(UnitPropagationListener upl) {
137 for (int q : lits) {
138 voc.watches(q ^ 1).remove(this);
139 }
140 }
141
142
143
144
145
146
147 public boolean propagate(UnitPropagationListener s, int p) {
148
149 voc.watch(p, this);
150
151 if (counter == maxUnsatisfied)
152 return false;
153
154 counter++;
155 voc.undos(p).push(this);
156
157
158 if (counter == maxUnsatisfied)
159 for (int q : lits) {
160 if (voc.isUnassigned(q) && !s.enqueue(q, this)) {
161 return false;
162 }
163 }
164 return true;
165 }
166
167
168
169
170
171
172 public boolean simplify() {
173 return false;
174 }
175
176
177
178
179
180
181 public void undo(int p) {
182 counter--;
183 }
184
185
186
187
188
189
190 public void calcReason(int p, IVecInt outReason) {
191 int c = (p == ILits.UNDEFINED) ? -1 : 0;
192 for (int q : lits) {
193 if (voc.isFalsified(q)) {
194 outReason.push(q ^ 1);
195 if (++c == maxUnsatisfied)
196 return;
197 }
198 }
199 }
200
201
202
203
204
205
206 public boolean learnt() {
207
208 return false;
209 }
210
211
212
213
214
215
216 public double getActivity() {
217
218 return 0;
219 }
220
221
222
223
224
225
226 public void incActivity(double claInc) {
227
228
229 }
230
231
232
233
234 public boolean locked() {
235
236
237 return true;
238 }
239
240 public void setLearnt() {
241 throw new UnsupportedOperationException();
242 }
243
244 public void register() {
245 throw new UnsupportedOperationException();
246 }
247
248 public int size() {
249 return lits.length;
250 }
251
252 public int get(int i) {
253 return lits[i];
254 }
255
256 public void rescaleBy(double d) {
257 throw new UnsupportedOperationException();
258 }
259
260 public void assertConstraint(UnitPropagationListener s) {
261 throw new UnsupportedOperationException();
262 }
263
264
265
266
267
268
269 @Override
270 public String toString() {
271 StringBuffer stb = new StringBuffer();
272 stb.append("Card (" + lits.length + ") : ");
273 for (int i = 0; i < lits.length; i++) {
274
275 stb.append(" + ");
276 stb.append(Lits.toString(this.lits[i]));
277 stb.append("[");
278 stb.append(voc.valueToString(lits[i]));
279 stb.append("@");
280 stb.append(voc.getLevel(lits[i]));
281 stb.append("]");
282 stb.append(" ");
283 stb.append(" ");
284 }
285 stb.append(">= ");
286 stb.append(size() - maxUnsatisfied);
287
288 return stb.toString();
289 }
290
291
292
293
294 public void forwardActivity(double claInc) {
295
296
297 }
298
299 }