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;
31
32 import java.io.PrintWriter;
33
34 import org.sat4j.core.Vec;
35 import org.sat4j.reader.Reader;
36 import org.sat4j.specs.ContradictionException;
37 import org.sat4j.specs.ILogAble;
38 import org.sat4j.specs.IOptimizationProblem;
39 import org.sat4j.specs.IProblem;
40 import org.sat4j.specs.ISolver;
41 import org.sat4j.specs.IVec;
42 import org.sat4j.specs.IVecInt;
43 import org.sat4j.specs.TimeoutException;
44 import org.sat4j.tools.Backbone;
45 import org.sat4j.tools.LexicoDecorator;
46 import org.sat4j.tools.SolutionFoundListener;
47
48
49
50
51
52
53
54
55
56 public interface ILauncherMode extends SolutionFoundListener {
57
58 String SOLUTION_PREFIX = "v ";
59
60 String ANSWER_PREFIX = "s ";
61
62 String CURRENT_OPTIMUM_VALUE_PREFIX = "o ";
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 void displayResult(ISolver solver, IProblem problem, ILogAble logger,
84 PrintWriter out, Reader reader, long beginTime,
85 boolean displaySolutionLine);
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 void solve(IProblem problem, Reader reader, ILogAble logger,
102 PrintWriter out, long beginTime);
103
104
105
106
107
108
109
110 void setIncomplete(boolean isIncomplete);
111
112
113
114
115
116
117
118 ExitCode getCurrentExitCode();
119
120
121
122
123
124 void setExitCode(ExitCode exitCode);
125
126
127
128
129
130 ILauncherMode DECISION = new ILauncherMode() {
131
132 private ExitCode exitCode = ExitCode.UNKNOWN;
133
134 public void displayResult(ISolver solver, IProblem problem,
135 ILogAble logger, PrintWriter out, Reader reader,
136 long beginTime, boolean displaySolutionLine) {
137 if (solver != null) {
138 out.flush();
139 double wallclocktime = (System.currentTimeMillis() - beginTime) / 1000.0;
140 solver.printStat(out);
141 solver.printInfos(out);
142 out.println(ANSWER_PREFIX + exitCode);
143 if (exitCode != ExitCode.UNKNOWN
144 && exitCode != ExitCode.UNSATISFIABLE) {
145 int[] model = solver.model();
146 if (System.getProperty("prime") != null) {
147 int initiallength = model.length;
148 logger.log("returning a prime implicant ...");
149 long beginpi = System.currentTimeMillis();
150 model = solver.primeImplicant();
151 long endpi = System.currentTimeMillis();
152 logger.log("removed " + (initiallength - model.length)
153 + " literals");
154 logger.log("pi computation time: " + (endpi - beginpi)
155 + " ms");
156 }
157 if (System.getProperty("backbone") != null) {
158 logger.log("computing the backbone of the formula ...");
159 long beginpi = System.currentTimeMillis();
160 model = solver.primeImplicant();
161 try {
162 IVecInt backbone = Backbone.compute(solver, model);
163 long endpi = System.currentTimeMillis();
164 out.print(solver.getLogPrefix());
165 reader.decode(backbone.toArray(), out);
166 out.println();
167 logger.log("backbone computation time: "
168 + (endpi - beginpi) + " ms");
169 } catch (TimeoutException e) {
170 logger.log("timeout, cannot compute the backbone.");
171 }
172
173 }
174 if (nbSolutionFound >= 1) {
175 logger.log("Found " + nbSolutionFound + " solution(s)");
176 }
177 out.print(SOLUTION_PREFIX);
178 reader.decode(model, out);
179 out.println();
180 }
181 logger.log("Total wall clock time (in seconds) : " + wallclocktime);
182 }
183 }
184
185 private int nbSolutionFound;
186
187 private PrintWriter out;
188 private long beginTime;
189
190 public void solve(IProblem problem, Reader reader, ILogAble logger,
191 PrintWriter out, long beginTime) {
192 this.exitCode = ExitCode.UNKNOWN;
193 this.out = out;
194 this.nbSolutionFound = 0;
195 this.beginTime = beginTime;
196 try {
197 if (problem.isSatisfiable()) {
198 if (this.exitCode == ExitCode.UNKNOWN) {
199 this.exitCode = ExitCode.SATISFIABLE;
200 }
201 } else {
202 if (this.exitCode == ExitCode.UNKNOWN) {
203 this.exitCode = ExitCode.UNSATISFIABLE;
204 }
205 }
206 } catch (TimeoutException e) {
207 logger.log("timeout");
208 }
209
210 }
211
212 public void setIncomplete(boolean isIncomplete) {
213 }
214
215 public ExitCode getCurrentExitCode() {
216 return this.exitCode;
217 };
218
219 public void onSolutionFound(int[] solution) {
220 this.nbSolutionFound++;
221 this.exitCode = ExitCode.SATISFIABLE;
222 this.out.printf("c Found solution #%d (%.2f)s%n", nbSolutionFound,
223 (System.currentTimeMillis() - beginTime) / 1000.0);
224 }
225
226 public void onSolutionFound(IVecInt solution) {
227 throw new UnsupportedOperationException("Not implemented yet!");
228 }
229
230 public void onUnsatTermination() {
231 if (this.exitCode == ExitCode.SATISFIABLE) {
232 this.exitCode = ExitCode.OPTIMUM_FOUND;
233 }
234 }
235
236 public void setExitCode(ExitCode exitCode) {
237 this.exitCode = exitCode;
238 }
239 };
240
241
242
243
244
245
246
247 ILauncherMode OPTIMIZATION = new ILauncherMode() {
248
249 private int nbSolutions;
250
251 private ExitCode exitCode = ExitCode.UNKNOWN;
252
253 private boolean isIncomplete = false;
254
255 public void setIncomplete(boolean isIncomplete) {
256 this.isIncomplete = isIncomplete;
257 }
258
259 public void displayResult(ISolver solver, IProblem problem,
260 ILogAble logger, PrintWriter out, Reader reader,
261 long beginTime, boolean displaySolutionLine) {
262 if (solver == null) {
263 return;
264 }
265 System.out.flush();
266 out.flush();
267 solver.printStat(out);
268 solver.printInfos(out);
269 out.println(ANSWER_PREFIX + exitCode);
270 if (exitCode == ExitCode.SATISFIABLE
271 || exitCode == ExitCode.OPTIMUM_FOUND || isIncomplete
272 && exitCode == ExitCode.UPPER_BOUND) {
273 assert this.nbSolutions > 0;
274 logger.log("Found " + this.nbSolutions + " solution(s)");
275
276 if (displaySolutionLine) {
277 out.print(SOLUTION_PREFIX);
278 reader.decode(problem.model(), out);
279 out.println();
280 }
281 IOptimizationProblem optproblem = (IOptimizationProblem) problem;
282 if (!optproblem.hasNoObjectiveFunction()) {
283 String objvalue;
284 if (optproblem instanceof LexicoDecorator<?>) {
285 IVec<Number> values = new Vec<Number>();
286 LexicoDecorator<?> lexico = (LexicoDecorator<?>) optproblem;
287 for (int i = 0; i < lexico.numberOfCriteria(); i++) {
288 values.push(lexico.getObjectiveValue(i));
289 }
290 objvalue = values.toString();
291
292 } else {
293 objvalue = optproblem.getObjectiveValue().toString();
294 }
295 logger.log("objective function=" + objvalue);
296 }
297 }
298
299 logger.log("Total wall clock time (in seconds): "
300 + (System.currentTimeMillis() - beginTime) / 1000.0);
301 }
302
303 public void solve(IProblem problem, Reader reader, ILogAble logger,
304 PrintWriter out, long beginTime) {
305 boolean isSatisfiable = false;
306 this.nbSolutions = 0;
307 IOptimizationProblem optproblem = (IOptimizationProblem) problem;
308 exitCode = ExitCode.UNKNOWN;
309
310 try {
311 while (optproblem.admitABetterSolution()) {
312 ++this.nbSolutions;
313 if (!isSatisfiable) {
314 if (optproblem.nonOptimalMeansSatisfiable()) {
315 logger.log("SATISFIABLE");
316 exitCode = ExitCode.SATISFIABLE;
317 if (optproblem.hasNoObjectiveFunction()) {
318 return;
319 }
320 } else if (isIncomplete) {
321 exitCode = ExitCode.UPPER_BOUND;
322 }
323 isSatisfiable = true;
324 logger.log("OPTIMIZING...");
325 }
326 logger.log("Got one! Elapsed wall clock time (in seconds):"
327 + (System.currentTimeMillis() - beginTime) / 1000.0);
328 out.println(CURRENT_OPTIMUM_VALUE_PREFIX
329 + optproblem.getObjectiveValue());
330 optproblem.discardCurrentSolution();
331 }
332 if (isSatisfiable) {
333 exitCode = ExitCode.OPTIMUM_FOUND;
334 } else {
335 exitCode = ExitCode.UNSATISFIABLE;
336 }
337 } catch (ContradictionException ex) {
338 assert isSatisfiable;
339 exitCode = ExitCode.OPTIMUM_FOUND;
340 } catch (TimeoutException e) {
341 logger.log("timeout");
342 }
343
344 }
345
346 public ExitCode getCurrentExitCode() {
347 return exitCode;
348 }
349
350 public void onSolutionFound(int[] solution) {
351 throw new UnsupportedOperationException("Not implemented yet!");
352 }
353
354 public void onSolutionFound(IVecInt solution) {
355 throw new UnsupportedOperationException("Not implemented yet!");
356 }
357
358 public void onUnsatTermination() {
359
360 }
361
362 public void setExitCode(ExitCode exitCode) {
363 this.exitCode = exitCode;
364 }
365 };
366
367 }