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