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