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.BufferedReader;
33 import java.io.FileNotFoundException;
34 import java.io.IOException;
35 import java.io.InputStreamReader;
36 import java.io.ObjectInputStream;
37 import java.io.PrintWriter;
38 import java.io.Serializable;
39 import java.net.URL;
40 import java.util.Properties;
41
42 import org.sat4j.core.ASolverFactory;
43 import org.sat4j.reader.ParseFormatException;
44 import org.sat4j.reader.Reader;
45 import org.sat4j.specs.ContradictionException;
46 import org.sat4j.specs.ILogAble;
47 import org.sat4j.specs.IProblem;
48 import org.sat4j.specs.ISolver;
49 import org.sat4j.specs.ISolverService;
50 import org.sat4j.specs.TimeoutException;
51 import org.sat4j.tools.ModelIteratorToSATAdapter;
52 import org.sat4j.tools.RupSearchListener;
53 import org.sat4j.tools.SearchEnumeratorListener;
54 import org.sat4j.tools.SearchMinOneListener;
55
56
57
58
59
60
61
62
63 public abstract class AbstractLauncher implements Serializable, ILogAble {
64
65
66
67
68 private static final long serialVersionUID = 1L;
69
70 public static final String COMMENT_PREFIX = "c ";
71
72 protected long beginTime;
73
74 protected ExitCode exitCode = ExitCode.UNKNOWN;
75
76 protected Reader reader;
77
78 protected transient PrintWriter out = new PrintWriter(System.out, true);
79
80 private boolean displaySolutionLine = true;
81
82 protected transient Thread shutdownHook = new Thread() {
83 @Override
84 public void run() {
85 displayResult();
86 }
87 };
88
89 protected ISolver solver;
90
91 protected IProblem problem;
92
93 public boolean silent = false;
94
95 protected boolean prime = System.getProperty("prime") != null;
96
97 private ILauncherMode launcherMode = ILauncherMode.DECISION;
98
99 protected void setLauncherMode(ILauncherMode launcherMode) {
100 this.launcherMode = launcherMode;
101 }
102
103 protected void setIncomplete(boolean isIncomplete) {
104 this.launcherMode.setIncomplete(isIncomplete);
105 }
106
107 protected AbstractLauncher() {
108 Runtime.getRuntime().addShutdownHook(this.shutdownHook);
109 }
110
111 protected void displayResult() {
112 launcherMode.displayResult(solver, problem, this, out, reader,
113 beginTime, displaySolutionLine);
114 }
115
116 public abstract void usage();
117
118
119
120
121 protected final void displayHeader() {
122 displayLicense();
123 URL url = AbstractLauncher.class.getResource("/sat4j.version");
124 if (url == null) {
125 log("no version file found!!!");
126 } else {
127 BufferedReader in = null;
128 try {
129 in = new BufferedReader(new InputStreamReader(url.openStream()));
130 log("version " + in.readLine());
131 } catch (IOException e) {
132 log("c ERROR: " + e.getMessage());
133 } finally {
134 if (in != null) {
135 try {
136 in.close();
137 } catch (IOException e) {
138 log("c ERROR: " + e.getMessage());
139 }
140 }
141 }
142 }
143 Properties prop = System.getProperties();
144 String[] infoskeys = {
145 "java.runtime.name", "java.vm.name", "java.vm.version", "java.vm.vendor", "sun.arch.data.model", "java.version", "os.name", "os.version", "os.arch" };
146 for (String key : infoskeys) {
147 log(key
148 + (key.length() < 14 ? "\t\t" : "\t") + prop.getProperty(key));
149 }
150 Runtime runtime = Runtime.getRuntime();
151 log("Free memory \t\t" + runtime.freeMemory());
152 log("Max memory \t\t" + runtime.maxMemory());
153 log("Total memory \t\t" + runtime.totalMemory());
154 log("Number of processors \t" + runtime.availableProcessors());
155 }
156
157 public void displayLicense() {
158 log("SAT4J: a SATisfiability library for Java (c) 2004-2013 Artois University and CNRS");
159 log("This is free software under the dual EPL/GNU LGPL licenses.");
160 log("See www.sat4j.org for details.");
161 }
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176 protected IProblem readProblem(String problemname)
177 throws ParseFormatException, IOException, ContradictionException {
178 log("solving " + problemname);
179 log("reading problem ... ");
180 this.reader = createReader(this.solver, problemname);
181 IProblem aProblem = this.reader.parseInstance(problemname);
182 log("... done. Wall clock time "
183 + (System.currentTimeMillis() - this.beginTime) / 1000.0 + "s.");
184 log("declared #vars " + aProblem.nVars());
185 if (this.solver.nVars() < this.solver.realNumberOfVariables()) {
186 log("internal #vars " + this.solver.realNumberOfVariables());
187 }
188 log("#constraints " + aProblem.nConstraints());
189 aProblem.printInfos(this.out);
190 if (System.getProperty("UNSATPROOF") != null) {
191 String proofFile = problemname + ".rupproof";
192 this.solver
193 .setSearchListener(new RupSearchListener<ISolverService>(
194 proofFile));
195 if (!this.silent) {
196 System.out.println(this.solver.getLogPrefix()
197 + "Generating unsat proof in file " + proofFile);
198 }
199 }
200 return aProblem;
201 }
202
203 protected abstract Reader createReader(ISolver theSolver, String problemname);
204
205 public void run(String[] args) {
206
207 try {
208 displayHeader();
209 this.solver = configureSolver(args);
210 if (this.solver == null) {
211 usage();
212 return;
213 }
214 if (!this.silent) {
215 this.solver.setVerbose(true);
216 }
217 String all = System.getProperty("all");
218 if (all != null) {
219 if ("external".equals(all)) {
220 this.solver = new ModelIteratorToSATAdapter(this.solver,
221 launcherMode);
222 System.out.println(this.solver.getLogPrefix()
223 + "model enumeration using the external way");
224 } else {
225 SearchEnumeratorListener enumerator = new SearchEnumeratorListener(
226 launcherMode);
227 this.solver.setSearchListener(enumerator);
228 System.out.println(this.solver.getLogPrefix()
229 + "model enumeration using the internal way");
230 }
231 }
232 if (System.getProperty("minone") != null) {
233 SearchMinOneListener minone = new SearchMinOneListener(
234 launcherMode);
235 this.solver.setSearchListener(minone);
236 }
237 String instanceName = getInstanceName(args);
238 if (instanceName == null) {
239 usage();
240 return;
241 }
242 this.beginTime = System.currentTimeMillis();
243 this.problem = readProblem(instanceName);
244 try {
245 solve(this.problem);
246 } catch (TimeoutException e) {
247 log("timeout");
248 }
249 } catch (FileNotFoundException e) {
250 System.err.println("FATAL " + e.getLocalizedMessage());
251 } catch (IOException e) {
252 System.err.println("FATAL " + e.getLocalizedMessage());
253 } catch (ContradictionException e) {
254 this.exitCode = ExitCode.UNSATISFIABLE;
255 this.launcherMode.setExitCode(ExitCode.UNSATISFIABLE);
256 log("(trivial inconsistency)");
257 } catch (ParseFormatException e) {
258 System.err.println("FATAL " + e.getLocalizedMessage());
259 }
260 }
261
262 protected abstract String getInstanceName(String[] args);
263
264 protected abstract ISolver configureSolver(String[] args);
265
266
267
268
269
270
271 public void log(String message) {
272 if (!this.silent) {
273 this.out.println(COMMENT_PREFIX + message);
274 }
275 }
276
277 protected void solve(IProblem problem) throws TimeoutException {
278 launcherMode.solve(problem, reader, this, out, beginTime);
279 this.setExitCode(launcherMode.getCurrentExitCode());
280 }
281
282
283
284
285
286
287
288 protected void setDisplaySolutionLine(boolean value) {
289 this.displaySolutionLine = value;
290 }
291
292
293
294
295
296
297
298 public final void setExitCode(ExitCode exitCode) {
299 this.exitCode = exitCode;
300 }
301
302
303
304
305
306
307 public final ExitCode getExitCode() {
308 return this.exitCode;
309 }
310
311
312
313
314
315
316
317 public final long getBeginTime() {
318 return this.beginTime;
319 }
320
321
322
323
324
325 public final Reader getReader() {
326 return this.reader;
327 }
328
329
330
331
332
333
334
335 public void setLogWriter(PrintWriter out) {
336 this.out = out;
337 }
338
339 public PrintWriter getLogWriter() {
340 return this.out;
341 }
342
343 protected void setSilent(boolean b) {
344 this.silent = b;
345 }
346
347 private void readObject(ObjectInputStream stream) throws IOException,
348 ClassNotFoundException {
349 stream.defaultReadObject();
350 this.out = new PrintWriter(System.out, true);
351 this.shutdownHook = new Thread() {
352 @Override
353 public void run() {
354 displayResult();
355 }
356 };
357 }
358
359 protected <T extends ISolver> void showAvailableSolvers(
360 ASolverFactory<T> afactory) {
361
362
363
364
365
366
367
368 showAvailableSolvers(afactory, "");
369 }
370
371 protected <T extends ISolver> void showAvailableSolvers(
372 ASolverFactory<T> afactory, String framework) {
373 if (afactory != null) {
374 if (framework.length() > 0) {
375 log("Available solvers for " + framework + ": ");
376 } else {
377 log("Available solvers: ");
378 }
379 String[] names = afactory.solverNames();
380 for (String name : names) {
381 log(name);
382 }
383 }
384 }
385 }