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
79 private static final XplainStrategy xplainStrategy = new QuickXplainStrategy();
80
81 public Xplain(T solver) {
82 super(solver);
83 }
84
85 @Override
86 public IConstr addClause(IVecInt literals) throws ContradictionException {
87 int newvar = createNewVar(literals);
88 literals.push(newvar);
89 IConstr constr = super.addClause(literals);
90 if (constr == null) {
91 discardLastestVar();
92 } else {
93 constrs.put(newvar, constr);
94 }
95 return constr;
96 }
97
98
99
100
101
102
103
104 protected int createNewVar(IVecInt literals) {
105 if (pooledVarId) {
106 pooledVarId = false;
107 return lastCreatedVar;
108 }
109 lastCreatedVar = nextFreeVarId(true);
110 return lastCreatedVar;
111 }
112
113 protected void discardLastestVar() {
114 pooledVarId = true;
115 }
116
117 @Override
118 public IConstr addAtLeast(IVecInt literals, int degree)
119 throws ContradictionException {
120 throw new UnsupportedOperationException();
121 }
122
123 @Override
124 public IConstr addAtMost(IVecInt literals, int degree)
125 throws ContradictionException {
126 throw new UnsupportedOperationException();
127 }
128
129
130
131
132 private static final long serialVersionUID = 1L;
133
134
135
136
137
138
139 public Collection<IConstr> explain() throws TimeoutException {
140 assert !isSatisfiable(assump);
141 ISolver solver = decorated();
142 if (solver instanceof IOptimizationProblem) {
143 solver = ((SolverDecorator<? extends ISolver>) solver).decorated();
144 }
145 IVecInt keys = xplainStrategy.explain(solver, constrs, assump);
146 Collection<IConstr> explanation = new ArrayList<IConstr>(keys.size());
147 for (IteratorInt it = keys.iterator(); it.hasNext();) {
148 explanation.add(constrs.get(it.next()));
149 }
150 return explanation;
151 }
152
153
154
155
156 public void cancelExplanation() {
157 xplainStrategy.cancelExplanationComputation();
158 }
159
160
161
162
163
164 public Collection<IConstr> getConstraints() {
165 return constrs.values();
166 }
167
168 @Override
169 public int[] findModel() throws TimeoutException {
170 assump = VecInt.EMPTY;
171 IVecInt extraVariables = new VecInt();
172 for (Integer p : constrs.keySet()) {
173 extraVariables.push(-p);
174 }
175 return super.findModel(extraVariables);
176 }
177
178 @Override
179 public int[] findModel(IVecInt assumps) throws TimeoutException {
180 assump = assumps;
181 IVecInt extraVariables = new VecInt();
182 assumps.copyTo(extraVariables);
183 for (Integer p : constrs.keySet()) {
184 extraVariables.push(-p);
185 }
186 return super.findModel(extraVariables);
187 }
188
189 @Override
190 public boolean isSatisfiable() throws TimeoutException {
191 assump = VecInt.EMPTY;
192 IVecInt extraVariables = new VecInt();
193 for (Integer p : constrs.keySet()) {
194 extraVariables.push(-p);
195 }
196 return super.isSatisfiable(extraVariables);
197 }
198
199 @Override
200 public boolean isSatisfiable(boolean global) throws TimeoutException {
201 assump = VecInt.EMPTY;
202 IVecInt extraVariables = new VecInt();
203 for (Integer p : constrs.keySet()) {
204 extraVariables.push(-p);
205 }
206 return super.isSatisfiable(extraVariables, global);
207 }
208
209 @Override
210 public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
211 assump = assumps;
212 IVecInt extraVariables = new VecInt();
213 assumps.copyTo(extraVariables);
214 for (Integer p : constrs.keySet()) {
215 extraVariables.push(-p);
216 }
217 return super.isSatisfiable(extraVariables);
218 }
219
220 @Override
221 public boolean isSatisfiable(IVecInt assumps, boolean global)
222 throws TimeoutException {
223 assump = assumps;
224 IVecInt extraVariables = new VecInt();
225 assumps.copyTo(extraVariables);
226 for (Integer p : constrs.keySet()) {
227 extraVariables.push(-p);
228 }
229 return super.isSatisfiable(extraVariables, global);
230 }
231
232 @Override
233 public int[] model() {
234 int[] fullmodel = super.model();
235 int[] model = new int[fullmodel.length - constrs.size()];
236 int j = 0;
237 for (int i = 0; i < fullmodel.length; i++) {
238 if (constrs.get(Math.abs(fullmodel[i])) == null) {
239 model[j++] = fullmodel[i];
240 }
241 }
242 return model;
243 }
244
245 }