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