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.Map;
31 import java.util.Set;
32
33 import org.sat4j.core.VecInt;
34 import org.sat4j.specs.ISolver;
35 import org.sat4j.specs.IVecInt;
36 import org.sat4j.specs.IteratorInt;
37 import org.sat4j.specs.TimeoutException;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public class QuickXplainStrategy implements MinimizationStrategy {
65
66 private boolean computationCanceled;
67
68 public void cancelExplanationComputation() {
69 computationCanceled = true;
70 }
71
72 public IVecInt explain(ISolver solver, Map<Integer, ?> constrs,
73 IVecInt assumps) throws TimeoutException {
74 computationCanceled = false;
75 IVecInt encodingAssumptions = new VecInt(constrs.size()
76 + assumps.size());
77 assumps.copyTo(encodingAssumptions);
78 IVecInt firstExplanation = solver.unsatExplanation();
79 IVecInt results = new VecInt(firstExplanation.size());
80 if (firstExplanation.size() == 1) {
81 results.push(-firstExplanation.get(0));
82 return results;
83 }
84 if (solver.isVerbose()) {
85 System.out.print(solver.getLogPrefix() + "initial unsat core ");
86 firstExplanation.sort();
87 for (IteratorInt it = firstExplanation.iterator(); it.hasNext();) {
88 System.out.print(constrs.get(-it.next()));
89 System.out.print(" ");
90 }
91 System.out.println();
92 }
93 for (int i = 0; i < firstExplanation.size();) {
94 if (assumps.contains(firstExplanation.get(i))) {
95 firstExplanation.delete(i);
96 } else {
97 i++;
98 }
99 }
100 Set<Integer> constraintsVariables = constrs.keySet();
101 IVecInt remainingVariables = new VecInt(constraintsVariables.size());
102 for (Integer v : constraintsVariables) {
103 remainingVariables.push(v);
104 }
105 int p;
106 for (IteratorInt it = firstExplanation.iterator(); it.hasNext();) {
107 p = it.next();
108 if (p < 0) {
109 p = -p;
110 }
111 remainingVariables.remove(p);
112 encodingAssumptions.push(p);
113 }
114 int unsatcorelimit = encodingAssumptions.size() - 1;
115
116 remainingVariables.copyTo(encodingAssumptions);
117 computeExplanation(solver, constrs, encodingAssumptions,
118 assumps.size(), unsatcorelimit, results);
119 return results;
120 }
121
122 private void computeExplanation(ISolver solver, Map<Integer, ?> constrs,
123 IVecInt encodingAssumptions, int start, int end, IVecInt result)
124 throws TimeoutException {
125 if (solver.isVerbose()) {
126 System.out.println(solver.getLogPrefix() + "qxplain " + start + "/"
127 + end);
128 }
129 if (!solver.isSatisfiable(encodingAssumptions)) {
130 return;
131 }
132 if (start == end) {
133 result.push(encodingAssumptions.get(start));
134 encodingAssumptions.set(start, -encodingAssumptions.get(start));
135 if (solver.isVerbose()) {
136 System.out.println(solver.getLogPrefix()
137 + constrs.get(-encodingAssumptions.get(start))
138 + " is mandatory ");
139 }
140 return;
141 }
142 int split = (end + start) / 2;
143 if (split < end) {
144 for (int j = start; j <= split; j++) {
145 encodingAssumptions.set(j, -encodingAssumptions.get(j));
146 }
147 computeExplanation(solver, constrs, encodingAssumptions, split + 1,
148 end, result);
149 }
150 if (start <= split) {
151 for (int j = start; j <= split; j++) {
152 encodingAssumptions.set(j, -encodingAssumptions.get(j));
153 }
154 computeExplanation(solver, constrs, encodingAssumptions, start,
155 split, result);
156 }
157 if (computationCanceled) {
158 throw new TimeoutException();
159 }
160 }
161
162 @Override
163 public String toString() {
164 return "QuickXplain (AAAI 2004 version) minimization strategy";
165 }
166
167 }