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 public class Ladder extends EncodingStrategyAdapter {
52
53
54
55
56 private static final long serialVersionUID = 1L;
57
58 @Override
59
60
61
62
63
64 public IConstr addAtMostOne(ISolver solver, IVecInt literals)
65 throws ContradictionException {
66 ConstrGroup group = new ConstrGroup(false);
67 final int n = literals.size() + 1;
68
69 int xN = solver.nextFreeVarId(true);
70 int y[] = new int[n - 1];
71
72 for (int i = 0; i < n - 1; i++) {
73 y[i] = solver.nextFreeVarId(true);
74 }
75
76 IVecInt clause = new VecInt();
77
78
79 for (int i = 1; i <= n - 2; i++) {
80 clause.push(-y[i]);
81 clause.push(y[i - 1]);
82 group.add(solver.addClause(clause));
83 clause.clear();
84 }
85
86
87 for (int i = 2; i <= n - 1; i++) {
88 clause.push(-y[i - 2]);
89 clause.push(y[i - 1]);
90 clause.push(literals.get(i - 1));
91 group.add(solver.addClause(clause));
92 clause.clear();
93 }
94
95
96 for (int i = 2; i <= n - 1; i++) {
97 clause.push(-literals.get(i - 1));
98 clause.push(y[i - 2]);
99 group.add(solver.addClause(clause));
100 clause.clear();
101 }
102
103
104 for (int i = 2; i <= n - 1; i++) {
105 clause.push(-literals.get(i - 1));
106 clause.push(-y[i - 1]);
107 group.add(solver.addClause(clause));
108 clause.clear();
109 }
110
111
112 clause.push(y[0]);
113 clause.push(literals.get(0));
114 group.add(solver.addClause(clause));
115 clause.clear();
116
117
118 clause.push(-y[0]);
119 clause.push(-literals.get(0));
120 group.add(solver.addClause(clause));
121 clause.clear();
122
123
124 clause.push(-y[n - 2]);
125 clause.push(xN);
126 group.add(solver.addClause(clause));
127 clause.clear();
128
129
130 clause.push(y[n - 2]);
131 clause.push(-xN);
132 group.add(solver.addClause(clause));
133 clause.clear();
134
135 return group;
136 }
137
138 @Override
139
140
141
142
143
144 public IConstr addExactlyOne(ISolver solver, IVecInt literals)
145 throws ContradictionException {
146 ConstrGroup group = new ConstrGroup(false);
147 final int n = literals.size();
148
149 IVecInt clause = new VecInt();
150
151 if (n == 1) {
152 clause.push(literals.get(0));
153 group.add(solver.addClause(clause));
154 return group;
155 }
156
157 int y[] = new int[n - 1];
158
159 for (int i = 0; i < n - 1; i++) {
160 y[i] = solver.nextFreeVarId(true);
161 }
162
163
164 for (int i = 1; i <= n - 2; i++) {
165 clause.push(-y[i]);
166 clause.push(y[i - 1]);
167 group.add(solver.addClause(clause));
168 clause.clear();
169 }
170
171
172 for (int i = 2; i <= n - 1; i++) {
173 clause.push(-y[i - 2]);
174 clause.push(y[i - 1]);
175 clause.push(literals.get(i - 1));
176 group.add(solver.addClause(clause));
177 clause.clear();
178 }
179
180
181 for (int i = 2; i <= n - 1; i++) {
182 clause.push(-literals.get(i - 1));
183 clause.push(y[i - 2]);
184 group.add(solver.addClause(clause));
185 clause.clear();
186 }
187
188
189 for (int i = 2; i <= n - 1; i++) {
190 clause.push(-literals.get(i - 1));
191 clause.push(-y[i - 1]);
192 group.add(solver.addClause(clause));
193 clause.clear();
194 }
195
196
197 clause.push(y[0]);
198 clause.push(literals.get(0));
199 group.add(solver.addClause(clause));
200 clause.clear();
201
202
203 clause.push(-y[0]);
204 clause.push(-literals.get(0));
205 group.add(solver.addClause(clause));
206 clause.clear();
207
208
209 clause.push(-y[n - 2]);
210 clause.push(literals.get(n - 1));
211 group.add(solver.addClause(clause));
212 clause.clear();
213
214
215 clause.push(y[n - 2]);
216 clause.push(-literals.get(n - 1));
217 group.add(solver.addClause(clause));
218 clause.clear();
219
220 return group;
221 }
222 }