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