View Javadoc

1   package org.sat4j.multicore;
2   
3   import java.io.PrintStream;
4   import java.io.PrintWriter;
5   import java.util.Map;
6   
7   import org.sat4j.core.ASolverFactory;
8   import org.sat4j.specs.ContradictionException;
9   import org.sat4j.specs.IConstr;
10  import org.sat4j.specs.ISolver;
11  import org.sat4j.specs.IVec;
12  import org.sat4j.specs.IVecInt;
13  import org.sat4j.specs.SearchListener;
14  import org.sat4j.specs.TimeoutException;
15  
16  public class ManyCore implements ISolver, OutcomeListener {
17  
18  	/**
19  	 * 
20  	 */
21  	private static final long serialVersionUID = 1L;
22  
23  	private String[] availableSolvers; // = { };
24  
25  	private ISolver[] solvers;
26  	private int numberOfSolvers;
27  	private int winnerId;
28  	private boolean needToWait;
29  	private boolean resultFound;
30  	private int remainingSolvers;
31  
32  	public ManyCore(ASolverFactory<? extends ISolver> factory, String ... solverNames) {
33  		availableSolvers = solverNames;
34  		Runtime runtime = Runtime.getRuntime();
35  		long memory = runtime.maxMemory();
36  		int numberOfCores = runtime.availableProcessors();
37  		if (memory > 1000000000L) {
38  			numberOfSolvers = numberOfCores;
39  		} else {
40  			numberOfSolvers = 1;
41  		}
42  		if (solverNames.length<numberOfSolvers) {
43  			throw new IllegalArgumentException("I need more solver names to run ManyCore on such computer!");
44  		}
45  		solvers = new ISolver[numberOfSolvers];
46  		for (int i = 0; i < numberOfSolvers; i++) {
47  			solvers[i] = factory.createSolverByName(
48  					availableSolvers[i]);
49  		}
50  	}
51  
52  	public void addAllClauses(IVec<IVecInt> clauses)
53  			throws ContradictionException {
54  		for (int i = 0; i < numberOfSolvers; i++) {
55  			solvers[i].addAllClauses(clauses);
56  		}
57  	}
58  
59  	public IConstr addAtLeast(IVecInt literals, int degree)
60  			throws ContradictionException {
61  		for (int i = 0; i < numberOfSolvers; i++) {
62  			solvers[i].addAtLeast(literals, degree);
63  		}
64  		return null;
65  	}
66  
67  	public IConstr addAtMost(IVecInt literals, int degree)
68  			throws ContradictionException {
69  		for (int i = 0; i < numberOfSolvers; i++) {
70  			solvers[i].addAtMost(literals, degree);
71  		}
72  		return null;
73  	}
74  
75  	public IConstr addClause(IVecInt literals) throws ContradictionException {
76  		for (int i = 0; i < numberOfSolvers; i++) {
77  			solvers[i].addClause(literals);
78  		}
79  		return null;
80  	}
81  
82  	public void clearLearntClauses() {
83  		for (int i = 0; i < numberOfSolvers; i++) {
84  			solvers[i].clearLearntClauses();
85  		}
86  	}
87  
88  	public void expireTimeout() {
89  		for (int i = 0; i < numberOfSolvers; i++) {
90  			solvers[i].expireTimeout();
91  		}
92  	}
93  
94  	public Map<String, Number> getStat() {
95  		return solvers[winnerId].getStat();
96  	}
97  
98  	public int getTimeout() {
99  		return solvers[0].getTimeout();
100 	}
101 	
102 	public long getTimeoutMs() {
103 		return solvers[0].getTimeoutMs();
104 	}
105 
106 	public int newVar() {
107 		throw new UnsupportedOperationException();
108 	}
109 
110 	public int newVar(int howmany) {
111 		int result = 0;
112 		for (int i = 0; i < numberOfSolvers; i++) {
113 			result = solvers[i].newVar(howmany);
114 		}
115 		return result;
116 	}
117 
118 	@Deprecated
119 	public void printStat(PrintStream out, String prefix) {
120 		solvers[winnerId].printStat(out, prefix);
121 	}
122 
123 	public void printStat(PrintWriter out, String prefix) {
124 		solvers[winnerId].printStat(out, prefix);
125 	}
126 
127 	public boolean removeConstr(IConstr c) {
128 		throw new UnsupportedOperationException();
129 	}
130 
131 	public void reset() {
132 		for (int i = 0; i < numberOfSolvers; i++) {
133 			solvers[i].reset();
134 		}
135 	}
136 
137 	public void setExpectedNumberOfClauses(int nb) {
138 		for (int i = 0; i < numberOfSolvers; i++) {
139 			solvers[i].setExpectedNumberOfClauses(nb);
140 		}
141 	}
142 
143 	public void setTimeout(int t) {
144 		for (int i = 0; i < numberOfSolvers; i++) {
145 			solvers[i].setTimeout(t);
146 		}
147 	}
148 
149 	public void setTimeoutMs(long t) {
150 		for (int i = 0; i < numberOfSolvers; i++) {
151 			solvers[i].setTimeoutMs(t);
152 		}
153 	}
154 
155 	public void setTimeoutOnConflicts(int count) {
156 		for (int i = 0; i < numberOfSolvers; i++) {
157 			solvers[i].setTimeoutOnConflicts(count);
158 		}
159 	}
160 
161 	public String toString(String prefix) {
162 		StringBuffer res = new StringBuffer();
163 		res.append("ManyCore solver with ");
164 		res.append(numberOfSolvers);
165         res.append(" solvers running in parallel");
166         res.append("\n");
167         for (int i=0;i<numberOfSolvers;i++) {
168         	res.append(solvers[i].toString(prefix));
169         	res.append("\n");
170         }
171 		return res.toString();
172 	}
173 
174 	public int[] findModel() throws TimeoutException {
175 		throw new UnsupportedOperationException();
176 	}
177 
178 	public int[] findModel(IVecInt assumps) throws TimeoutException {
179 		throw new UnsupportedOperationException();
180 	}
181 
182 	public boolean isSatisfiable() throws TimeoutException {
183 		remainingSolvers = numberOfSolvers;
184 		needToWait = true;
185 		for (int i = 0; i < numberOfSolvers; i++) {
186 			new Thread(new RunnableSolver(i, solvers[i], this)).start();
187 		}
188 		try {
189 			do {
190 				Thread.sleep(1000);
191 			} while (needToWait && remainingSolvers > 0);
192 		} catch (InterruptedException e) {
193 			// TODO: handle exception
194 		}
195 		if (remainingSolvers == 0) {
196 			throw new TimeoutException();
197 		}
198 		return resultFound;
199 	}
200 
201 	public boolean isSatisfiable(IVecInt assumps, boolean globalTimeout)
202 			throws TimeoutException {
203 		throw new UnsupportedOperationException();
204 	}
205 
206 	public boolean isSatisfiable(boolean globalTimeout) throws TimeoutException {
207 		throw new UnsupportedOperationException();
208 	}
209 
210 	public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
211 		throw new UnsupportedOperationException();
212 	}
213 
214 	public int[] model() {
215 		return solvers[winnerId].model();
216 	}
217 
218 	public boolean model(int var) {
219 		return solvers[winnerId].model(var);
220 	}
221 
222 	public int nConstraints() {
223 		return solvers[0].nConstraints();
224 	}
225 
226 	public int nVars() {
227 		return solvers[0].nVars();
228 	}
229 
230 	public void printInfos(PrintWriter out, String prefix) {
231 		for (int i = 0; i < numberOfSolvers; i++) {
232 			solvers[i].printInfos(out, prefix);
233 		}
234 	}
235 
236 	public synchronized void onFinishWithAnswer(boolean finished,
237 			boolean result, int index) {
238 		if (finished) {
239 			winnerId = index;
240 			resultFound = result;
241 			for (int i = 0; i < numberOfSolvers; i++) {
242 				if (i != winnerId)
243 					solvers[i].expireTimeout();
244 			}
245 			System.out.println("c And the winner is "+availableSolvers[winnerId]);
246 			needToWait = false;
247 		} else {
248 			remainingSolvers--;
249 		}
250 	}
251 
252 	public boolean isDBSimplificationAllowed() {
253 		return solvers[0].isDBSimplificationAllowed();
254 	}
255 
256 	public void setDBSimplificationAllowed(boolean status) {
257 		for (int i = 0; i < numberOfSolvers; i++) {
258 			solvers[i].setDBSimplificationAllowed(status);
259 		}		
260 	}
261 
262 	public void setSearchListener(SearchListener sl) {
263 		for (int i = 0; i < numberOfSolvers; i++) {
264 			solvers[i].setSearchListener(sl);
265 		}	
266 		
267 	}
268 
269 	public int nextFreeVarId(boolean reserve) {
270 		return solvers[0].nextFreeVarId(reserve);
271 	}
272 
273 	public IConstr addBlockingClause(IVecInt literals)
274 			throws ContradictionException {
275 		for (int i = 0; i < numberOfSolvers; i++) {
276 			solvers[i].addBlockingClause(literals);
277 		}
278 		return null;
279 	}
280 
281 	public boolean removeSubsumedConstr(IConstr c) {
282 		boolean removed = true;
283 		for (int i = 0; i < numberOfSolvers; i++) {
284 			removed = removed & solvers[i].removeSubsumedConstr(c);
285 		}
286 		return removed;
287 	}
288 }
289 
290 interface OutcomeListener {
291 	void onFinishWithAnswer(boolean finished, boolean result, int index);
292 }
293 
294 class RunnableSolver implements Runnable {
295 
296 	private final int index;
297 	private final ISolver solver;
298 	private final OutcomeListener ol;
299 
300 	public RunnableSolver(int i, ISolver solver, OutcomeListener ol) {
301 		index = i;
302 		this.solver = solver;
303 		this.ol = ol;
304 	}
305 
306 	public void run() {
307 		try {
308 			boolean result = solver.isSatisfiable();
309 			ol.onFinishWithAnswer(true, result, index);
310 		} catch (TimeoutException e) {
311 			ol.onFinishWithAnswer(false, false, index);
312 		}
313 	}
314 
315 }