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.xplain;
29
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.HashMap;
33 import java.util.Map;
34
35 import org.sat4j.core.VecInt;
36 import org.sat4j.specs.ContradictionException;
37 import org.sat4j.specs.IConstr;
38 import org.sat4j.specs.IOptimizationProblem;
39 import org.sat4j.specs.ISolver;
40 import org.sat4j.specs.IVecInt;
41 import org.sat4j.specs.IteratorInt;
42 import org.sat4j.specs.TimeoutException;
43 import org.sat4j.tools.SolverDecorator;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 public class Xplain<T extends ISolver> extends SolverDecorator<T> {
71
72 protected Map<Integer, IConstr> constrs = new HashMap<Integer, IConstr>();
73
74 protected IVecInt assump;
75
76 private int lastCreatedVar;
77 private boolean pooledVarId = false;
78 private final IVecInt lastClause = new VecInt();
79
80 private static final XplainStrategy XPLAIN_STRATEGY = new QuickXplainStrategy();
81
82 public Xplain(T solver) {
83 super(solver);
84 }
85
86 @Override
87 public IConstr addClause(IVecInt literals) throws ContradictionException {
88 if (literals.equals(lastClause)) {
89
90 return null;
91 }
92 lastClause.clear();
93 literals.copyTo(lastClause);
94 int newvar = createNewVar(literals);
95 literals.push(newvar);
96 IConstr constr = super.addClause(literals);
97 if (constr == null) {
98 discardLastestVar();
99 } else {
100 constrs.put(newvar, constr);
101 }
102 return constr;
103 }
104
105
106
107
108
109
110
111 protected int createNewVar(IVecInt literals) {
112 if (pooledVarId) {
113 pooledVarId = false;
114 return lastCreatedVar;
115 }
116 lastCreatedVar = nextFreeVarId(true);
117 return lastCreatedVar;
118 }
119
120 protected void discardLastestVar() {
121 pooledVarId = true;
122 }
123
124 @Override
125 public IConstr addAtLeast(IVecInt literals, int degree)
126 throws ContradictionException {
127 throw new UnsupportedOperationException();
128 }
129
130 @Override
131 public IConstr addAtMost(IVecInt literals, int degree)
132 throws ContradictionException {
133 throw new UnsupportedOperationException();
134 }
135
136
137
138
139 private static final long serialVersionUID = 1L;
140
141
142
143
144
145
146 public Collection<IConstr> explain() throws TimeoutException {
147 assert !isSatisfiable(assump);
148 ISolver solver = decorated();
149 if (solver instanceof IOptimizationProblem) {
150 solver = ((SolverDecorator<? extends ISolver>) solver).decorated();
151 }
152 IVecInt keys = XPLAIN_STRATEGY.explain(solver, constrs, assump);
153 Collection<IConstr> explanation = new ArrayList<IConstr>(keys.size());
154 for (IteratorInt it = keys.iterator(); it.hasNext();) {
155 explanation.add(constrs.get(it.next()));
156 }
157 return explanation;
158 }
159
160
161
162
163 public void cancelExplanation() {
164 XPLAIN_STRATEGY.cancelExplanationComputation();
165 }
166
167
168
169
170
171 public Collection<IConstr> getConstraints() {
172 return constrs.values();
173 }
174
175 @Override
176 public int[] findModel() throws TimeoutException {
177 assump = VecInt.EMPTY;
178 IVecInt extraVariables = new VecInt();
179 for (Integer p : constrs.keySet()) {
180 extraVariables.push(-p);
181 }
182 return super.findModel(extraVariables);
183 }
184
185 @Override
186 public int[] findModel(IVecInt assumps) throws TimeoutException {
187 assump = assumps;
188 IVecInt extraVariables = new VecInt();
189 assumps.copyTo(extraVariables);
190 for (Integer p : constrs.keySet()) {
191 extraVariables.push(-p);
192 }
193 return super.findModel(extraVariables);
194 }
195
196 @Override
197 public boolean isSatisfiable() throws TimeoutException {
198 assump = VecInt.EMPTY;
199 IVecInt extraVariables = new VecInt();
200 for (Integer p : constrs.keySet()) {
201 extraVariables.push(-p);
202 }
203 return super.isSatisfiable(extraVariables);
204 }
205
206 @Override
207 public boolean isSatisfiable(boolean global) throws TimeoutException {
208 assump = VecInt.EMPTY;
209 IVecInt extraVariables = new VecInt();
210 for (Integer p : constrs.keySet()) {
211 extraVariables.push(-p);
212 }
213 return super.isSatisfiable(extraVariables, global);
214 }
215
216 @Override
217 public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
218 assump = assumps;
219 IVecInt extraVariables = new VecInt();
220 assumps.copyTo(extraVariables);
221 for (Integer p : constrs.keySet()) {
222 extraVariables.push(-p);
223 }
224 return super.isSatisfiable(extraVariables);
225 }
226
227 @Override
228 public boolean isSatisfiable(IVecInt assumps, boolean global)
229 throws TimeoutException {
230 assump = assumps;
231 IVecInt extraVariables = new VecInt();
232 assumps.copyTo(extraVariables);
233 for (Integer p : constrs.keySet()) {
234 extraVariables.push(-p);
235 }
236 return super.isSatisfiable(extraVariables, global);
237 }
238
239 @Override
240 public int[] model() {
241 int[] fullmodel = super.model();
242 if (fullmodel == null) {
243 return null;
244 }
245 int[] model = new int[fullmodel.length - constrs.size()];
246 int j = 0;
247 for (int i = 0; i < fullmodel.length; i++) {
248 if (constrs.get(Math.abs(fullmodel[i])) == null) {
249 model[j++] = fullmodel[i];
250 }
251 }
252 return model;
253 }
254
255 }