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.helper;
29
30 import java.util.Collection;
31 import java.util.HashMap;
32 import java.util.Map;
33
34 import org.sat4j.core.Vec;
35 import org.sat4j.core.VecInt;
36 import org.sat4j.specs.ContradictionException;
37 import org.sat4j.specs.ISolver;
38 import org.sat4j.specs.IVec;
39 import org.sat4j.specs.IVecInt;
40 import org.sat4j.specs.TimeoutException;
41
42
43
44
45
46
47
48
49
50
51 public class MappingHelper<T> {
52
53
54
55
56 private static final long serialVersionUID = 1L;
57
58 private final Map<T, Integer> mapToDimacs = new HashMap<T, Integer>();
59 private final IVec<T> mapToDomain;
60 final ISolver solver;
61
62 public MappingHelper(ISolver solver) {
63 this.solver = solver;
64 mapToDomain = new Vec<T>();
65 mapToDomain.push(null);
66 }
67
68 int getIntValue(T thing) {
69 Integer intValue = mapToDimacs.get(thing);
70 if (intValue == null) {
71 intValue = mapToDomain.size();
72 mapToDomain.push(thing);
73 mapToDimacs.put(thing, intValue);
74 }
75 return intValue;
76 }
77
78 public IVec<T> getSolution() {
79 int[] model = solver.model();
80 IVec<T> toInstall = new Vec<T>();
81 for (int i : model) {
82 if (i > 0) {
83 toInstall.push(mapToDomain.get(i));
84 }
85 }
86 return toInstall;
87 }
88
89 public boolean getBooleanValueFor(T t) {
90 return solver.model(getIntValue(t));
91 }
92
93 public boolean hasASolution() throws TimeoutException {
94 return solver.isSatisfiable();
95 }
96
97
98
99
100
101
102
103
104
105
106 public void addImplies(T x, T y) throws ContradictionException {
107 IVecInt clause = new VecInt();
108 clause.push(-getIntValue(x));
109 clause.push(getIntValue(y));
110 solver.addClause(clause);
111 }
112
113
114
115
116
117
118
119
120
121
122 public void addImplies(T[] x, T y) throws ContradictionException {
123 IVecInt clause = new VecInt();
124 for (T t : x) {
125 clause.push(-getIntValue(t));
126 clause.push(getIntValue(y));
127 solver.addClause(clause);
128 clause.clear();
129 }
130 }
131
132
133
134
135
136
137
138
139
140
141 public void addImplies(Collection<T> x, T y) throws ContradictionException {
142 IVecInt clause = new VecInt();
143 for (T t : x) {
144 clause.push(-getIntValue(t));
145 clause.push(getIntValue(y));
146 solver.addClause(clause);
147 clause.clear();
148 }
149 }
150
151
152
153
154
155
156
157
158
159
160
161 public void addImplies(T x, T[] y) throws ContradictionException {
162 IVecInt clause = new VecInt();
163 for (T t : y) {
164 clause.push(-getIntValue(x));
165 clause.push(getIntValue(t));
166 solver.addClause(clause);
167 clause.clear();
168 }
169 }
170
171
172
173
174
175
176
177
178
179
180
181 public void addImplies(T x, Collection<T> y) throws ContradictionException {
182 IVecInt clause = new VecInt();
183 for (T t : y) {
184 clause.push(-getIntValue(x));
185 clause.push(getIntValue(t));
186 solver.addClause(clause);
187 clause.clear();
188 }
189 }
190
191
192
193
194
195
196
197
198
199
200
201 public void addImplication(T x, T[] y) throws ContradictionException {
202 IVecInt clause = new VecInt();
203 clause.push(-getIntValue(x));
204 for (T t : y) {
205 clause.push(getIntValue(t));
206 }
207 solver.addClause(clause);
208 }
209
210
211
212
213
214
215
216
217
218
219
220 public void addImplication(T x, Collection<T> y)
221 throws ContradictionException {
222 IVecInt clause = new VecInt();
223 clause.push(-getIntValue(x));
224 for (T t : y) {
225 clause.push(getIntValue(t));
226 }
227 solver.addClause(clause);
228 }
229
230
231
232
233
234
235
236
237
238
239
240
241 public void addAtLeast(T[] x, int degree) throws ContradictionException {
242 IVecInt literals = new VecInt(x.length);
243 for (T t : x) {
244 literals.push(getIntValue(t));
245 }
246 solver.addAtLeast(literals, degree);
247 }
248
249
250
251
252
253
254
255
256
257
258
259
260 public void addAtLeast(Collection<T> x, int degree)
261 throws ContradictionException {
262 IVecInt literals = new VecInt(x.size());
263 for (T t : x) {
264 literals.push(getIntValue(t));
265 }
266 solver.addAtLeast(literals, degree);
267 }
268
269
270
271
272
273
274
275
276
277
278
279
280 public void addAtMost(T[] x, int degree) throws ContradictionException {
281 IVecInt literals = new VecInt(x.length);
282 for (T t : x) {
283 literals.push(getIntValue(t));
284 }
285 solver.addAtMost(literals, degree);
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299 public void addAtMost(Collection<T> x, int degree)
300 throws ContradictionException {
301 IVecInt literals = new VecInt(x.size());
302 for (T t : x) {
303 literals.push(getIntValue(t));
304 }
305 solver.addAtMost(literals, degree);
306 }
307
308 public void addExactlyOneOf(T... ts) throws ContradictionException {
309 IVecInt literals = new VecInt(ts.length);
310 for (T t : ts) {
311 literals.push(getIntValue(t));
312 }
313 solver.addAtMost(literals, 1);
314 solver.addClause(literals);
315 }
316
317
318
319
320
321
322
323
324
325 public void addImpliesEquivalence(T x, T y, T z) throws ContradictionException {
326 IVecInt literals = new VecInt();
327 literals.push(-getIntValue(x)).push(-getIntValue(y)).push(getIntValue(z));
328 solver.addClause(literals);
329 literals.clear();
330 literals.push(-getIntValue(x)).push(-getIntValue(z)).push(getIntValue(y));
331 solver.addClause(literals);
332 }
333
334
335
336
337
338
339 public void addConflict(Collection<T> things) throws ContradictionException {
340 IVecInt literals = new VecInt(things.size());
341 for (T t : things) {
342 literals.push(-getIntValue(t));
343 }
344 solver.addClause(literals);
345 }
346
347
348
349
350
351
352 public void addConflict(T... things) throws ContradictionException {
353 IVecInt literals = new VecInt(things.length);
354 for (T t : things) {
355 literals.push(-getIntValue(t));
356 }
357 solver.addClause(literals);
358 }
359
360 public void setTrue(T... things) throws ContradictionException {
361 IVecInt clause = new VecInt();
362 for (T thing : things) {
363 clause.push(getIntValue(thing));
364 solver.addClause(clause);
365 clause.clear();
366 }
367 }
368
369 public void setFalse(T... things) throws ContradictionException {
370 IVecInt clause = new VecInt();
371 for (T thing : things) {
372 clause.push(-getIntValue(thing));
373 solver.addClause(clause);
374 clause.clear();
375 }
376 }
377 }