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
29
30
31 package org.sat4j.tools.encoding;
32
33 import org.sat4j.core.ConstrGroup;
34 import org.sat4j.core.VecInt;
35 import org.sat4j.specs.ContradictionException;
36 import org.sat4j.specs.IConstr;
37 import org.sat4j.specs.ISolver;
38 import org.sat4j.specs.IVecInt;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class Binary extends EncodingStrategyAdapter {
58
59
60
61
62
63
64 @Override
65 public IConstr addAtMostOne(ISolver solver, IVecInt literals)
66 throws ContradictionException {
67 ConstrGroup group = new ConstrGroup(false);
68
69 final int n = literals.size();
70 final int p = (int) Math.ceil(Math.log(n) / Math.log(2));
71 final int k = (int) Math.pow(2, p) - n;
72
73 int y[] = new int[p];
74 for (int i = 0; i < p; i++) {
75 y[i] = solver.nextFreeVarId(true);
76 }
77
78 IVecInt clause = new VecInt();
79 String binary = "";
80
81 for (int i = 0; i < k; i++) {
82 binary = Integer.toBinaryString(i);
83 while (binary.length() != p - 1) {
84 binary = "0" + binary;
85 }
86
87 for (int j = 0; j < p - 1; j++) {
88 clause.push(-literals.get(i));
89 if (binary.charAt(j) == '0') {
90 clause.push(-y[j]);
91 } else {
92 clause.push(y[j]);
93 }
94 group.add(solver.addClause(clause));
95 clause.clear();
96
97 }
98 }
99
100 for (int i = k; i < n; i++) {
101 binary = Integer.toBinaryString(2 * k + i - k);
102 while (binary.length() != p) {
103 binary = "0" + binary;
104 }
105 for (int j = 0; j < p; j++) {
106 clause.push(-literals.get(i));
107 if (binary.charAt(j) == '0') {
108 clause.push(-y[j]);
109 } else {
110 clause.push(y[j]);
111 }
112 group.add(solver.addClause(clause));
113 clause.clear();
114 }
115
116 }
117
118 return group;
119 }
120
121 @Override
122 public IConstr addAtMost(ISolver solver, IVecInt literals, int k)
123 throws ContradictionException {
124
125 final int n = literals.size();
126 final int p = (int) Math.ceil(Math.log(n) / Math.log(2));
127
128 ConstrGroup group = new ConstrGroup(false);
129
130 int[][] b = new int[k][p];
131
132 for (int i = 0; i < k; i++) {
133 for (int j = 0; j < p; j++) {
134 b[i][j] = solver.nextFreeVarId(true);
135 }
136 }
137
138 int[][] t = new int[k][n];
139
140 for (int i = 0; i < k; i++) {
141 for (int j = 0; j < n; j++) {
142 t[i][j] = solver.nextFreeVarId(true);
143 }
144 }
145
146 int max, min;
147 IVecInt clause1 = new VecInt();
148 IVecInt clause2 = new VecInt();
149 String binary = "";
150 for (int i = 0; i < n; i++) {
151 max = Math.max(1, k - n + i + 1);
152 min = Math.min(i + 1, k);
153 clause1.push(-literals.get(i));
154
155 binary = Integer.toBinaryString(i);
156 while (binary.length() != p) {
157 binary = "0" + binary;
158 }
159
160 for (int g = max - 1; g < min; g++) {
161 clause1.push(t[g][i]);
162 for (int j = 0; j < p; j++) {
163 clause2.push(-t[g][i]);
164 if (binary.charAt(j) == '0') {
165 clause2.push(-b[g][j]);
166 } else {
167 clause2.push(b[g][j]);
168 }
169 group.add(solver.addClause(clause2));
170 clause2.clear();
171 }
172 }
173 group.add(solver.addClause(clause1));
174 clause1.clear();
175 }
176
177 return group;
178 }
179
180 @Override
181 public IConstr addAtLeast(ISolver solver, IVecInt literals, int k)
182 throws ContradictionException {
183
184 IVecInt newLits = new VecInt();
185 for (int i = 0; i < literals.size(); i++) {
186 newLits.push(-literals.get(i));
187 }
188
189 return addAtMost(solver, newLits, literals.size() - k);
190 }
191
192 @Override
193 public IConstr addExactlyOne(ISolver solver, IVecInt literals)
194 throws ContradictionException {
195 ConstrGroup group = new ConstrGroup();
196
197 group.add(addAtLeastOne(solver, literals));
198 group.add(addAtMostOne(solver, literals));
199
200 return group;
201 }
202
203 @Override
204 public IConstr addExactly(ISolver solver, IVecInt literals, int degree)
205 throws ContradictionException {
206 ConstrGroup group = new ConstrGroup();
207
208 group.add(addAtLeast(solver, literals, degree));
209 group.add(addAtMost(solver, literals, degree));
210
211 return group;
212 }
213 }