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