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