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