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