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
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 }