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.tools;
29
30 import org.sat4j.core.Vec;
31 import org.sat4j.core.VecInt;
32 import org.sat4j.specs.ContradictionException;
33 import org.sat4j.specs.IConstr;
34 import org.sat4j.specs.ISolver;
35 import org.sat4j.specs.IVec;
36 import org.sat4j.specs.IVecInt;
37
38
39
40
41
42
43
44 public class GateTranslator extends SolverDecorator<ISolver> {
45
46
47
48
49 private static final long serialVersionUID = 1L;
50
51 public GateTranslator(ISolver solver) {
52 super(solver);
53 }
54
55
56
57
58
59
60
61
62
63
64 public IConstr gateFalse(int y) throws ContradictionException {
65 IVecInt clause = new VecInt(2);
66 clause.push(-y);
67 return processClause(clause);
68 }
69
70
71
72
73
74
75
76
77
78 public IConstr gateTrue(int y) throws ContradictionException {
79 IVecInt clause = new VecInt(2);
80 clause.push(y);
81 return processClause(clause);
82 }
83
84
85
86
87
88
89
90
91
92
93
94
95 public IConstr[] ite(int y, int x1, int x2, int x3)
96 throws ContradictionException {
97 IConstr[] constrs = new IConstr[6];
98 IVecInt clause = new VecInt(5);
99
100
101 clause.push(-y).push(-x1).push(x2);
102 constrs[0] = processClause(clause);
103 clause.clear();
104 clause.push(-y).push(x1).push(x3);
105 constrs[1] = processClause(clause);
106
107
108
109
110
111
112
113 clause.clear();
114 clause.push(-x1).push(-x2).push(y);
115 constrs[2] = processClause(clause);
116 clause.clear();
117 clause.push(x1).push(-x3).push(y);
118 constrs[3] = processClause(clause);
119 clause.clear();
120 clause.push(-x2).push(-x3).push(y);
121 constrs[4] = processClause(clause);
122
123
124
125 clause.clear();
126 clause.push(-y).push(x2).push(x3);
127 constrs[5] = processClause(clause);
128 return constrs;
129 }
130
131
132
133
134
135
136
137
138
139
140 public IConstr[] and(int y, IVecInt literals) throws ContradictionException {
141
142 IConstr[] constrs = new IConstr[literals.size() + 1];
143
144 IVecInt clause = new VecInt(literals.size() + 2);
145 clause.push(y);
146 for (int i = 0; i < literals.size(); i++) {
147 clause.push(-literals.get(i));
148 }
149 constrs[0] = processClause(clause);
150 clause.clear();
151 for (int i = 0; i < literals.size(); i++) {
152
153 clause.clear();
154 clause.push(-y);
155 clause.push(literals.get(i));
156 constrs[i + 1] = processClause(clause);
157 }
158 return constrs;
159 }
160
161
162
163
164
165
166
167
168
169
170 public IConstr[] and(int y, int x1, int x2) throws ContradictionException {
171 IVecInt clause = new VecInt(4);
172 IConstr[] constrs = new IConstr[3];
173 clause.push(-y);
174 clause.push(x1);
175 constrs[0] = addClause(clause);
176 clause.clear();
177 clause.push(-y);
178 clause.push(x2);
179 constrs[1] = addClause(clause);
180 clause.clear();
181 clause.push(y);
182 clause.push(-x1);
183 clause.push(-x2);
184 constrs[2] = addClause(clause);
185 return constrs;
186 }
187
188
189
190
191
192
193
194
195
196 public IConstr[] or(int y, IVecInt literals) throws ContradictionException {
197
198
199 IConstr[] constrs = new IConstr[literals.size() + 1];
200 IVecInt clause = new VecInt(literals.size() + 2);
201 literals.copyTo(clause);
202 clause.push(-y);
203 constrs[0] = processClause(clause);
204 clause.clear();
205 for (int i = 0; i < literals.size(); i++) {
206
207 clause.clear();
208 clause.push(y);
209 clause.push(-literals.get(i));
210 constrs[i + 1] = processClause(clause);
211 }
212 return constrs;
213 }
214
215 private IConstr processClause(IVecInt clause) throws ContradictionException {
216 return addClause(clause);
217 }
218
219
220
221
222
223
224
225
226
227 public IConstr[] not(int y, int x) throws ContradictionException {
228 IConstr[] constrs = new IConstr[2];
229 IVecInt clause = new VecInt(3);
230
231
232 clause.push(-y).push(-x);
233 constrs[0] = processClause(clause);
234
235 clause.clear();
236 clause.push(y).push(x);
237 constrs[1] = processClause(clause);
238 return constrs;
239 }
240
241
242
243
244
245
246
247
248
249 public IConstr[] xor(int y, IVecInt literals) throws ContradictionException {
250 literals.push(-y);
251 int[] f = new int[literals.size()];
252 literals.copyTo(f);
253 IVec<IConstr> vconstrs = new Vec<IConstr>();
254 xor2Clause(f, 0, false, vconstrs);
255 IConstr[] constrs = new IConstr[vconstrs.size()];
256 vconstrs.copyTo(constrs);
257 return constrs;
258 }
259
260
261
262
263
264
265
266
267
268 public IConstr[] iff(int y, IVecInt literals) throws ContradictionException {
269 literals.push(y);
270 int[] f = new int[literals.size()];
271 literals.copyTo(f);
272 IVec<IConstr> vconstrs = new Vec<IConstr>();
273 iff2Clause(f, 0, false, vconstrs);
274 IConstr[] constrs = new IConstr[vconstrs.size()];
275 vconstrs.copyTo(constrs);
276 return constrs;
277 }
278
279 private void xor2Clause(int[] f, int prefix, boolean negation,
280 IVec<IConstr> constrs) throws ContradictionException {
281 if (prefix == f.length - 1) {
282 IVecInt clause = new VecInt(f.length + 1);
283 for (int i = 0; i < f.length - 1; ++i) {
284 clause.push(f[i]);
285 }
286 clause.push(f[f.length - 1] * (negation ? -1 : 1));
287 constrs.push(processClause(clause));
288 return;
289 }
290
291 if (negation) {
292 f[prefix] = -f[prefix];
293 xor2Clause(f, prefix + 1, false, constrs);
294 f[prefix] = -f[prefix];
295
296 xor2Clause(f, prefix + 1, true, constrs);
297 } else {
298 xor2Clause(f, prefix + 1, false, constrs);
299
300 f[prefix] = -f[prefix];
301 xor2Clause(f, prefix + 1, true, constrs);
302 f[prefix] = -f[prefix];
303 }
304 }
305
306 private void iff2Clause(int[] f, int prefix, boolean negation,
307 IVec<IConstr> constrs) throws ContradictionException {
308 if (prefix == f.length - 1) {
309 IVecInt clause = new VecInt(f.length + 1);
310 for (int i = 0; i < f.length - 1; ++i) {
311 clause.push(f[i]);
312 }
313 clause.push(f[f.length - 1] * (negation ? -1 : 1));
314 processClause(clause);
315 return;
316 }
317
318 if (negation) {
319 iff2Clause(f, prefix + 1, false, constrs);
320 f[prefix] = -f[prefix];
321 iff2Clause(f, prefix + 1, true, constrs);
322 f[prefix] = -f[prefix];
323 } else {
324 f[prefix] = -f[prefix];
325 iff2Clause(f, prefix + 1, false, constrs);
326 f[prefix] = -f[prefix];
327 iff2Clause(f, prefix + 1, true, constrs);
328 }
329 }
330
331 }