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 }