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 package org.sat4j.minisat.core;
27
28 import static org.sat4j.minisat.core.LiteralsUtils.neg;
29 import static org.sat4j.minisat.core.LiteralsUtils.var;
30
31 import java.io.PrintStream;
32 import java.io.PrintWriter;
33 import java.io.Serializable;
34 import java.lang.reflect.Field;
35 import java.math.BigInteger;
36 import java.util.Comparator;
37 import java.util.Map;
38 import java.util.Timer;
39 import java.util.TimerTask;
40
41 import org.sat4j.core.Vec;
42 import org.sat4j.core.VecInt;
43 import org.sat4j.specs.ContradictionException;
44 import org.sat4j.specs.IConstr;
45 import org.sat4j.specs.ISolver;
46 import org.sat4j.specs.IVec;
47 import org.sat4j.specs.IVecInt;
48 import org.sat4j.specs.TimeoutException;
49
50
51
52
53
54
55
56 public class Solver<L extends ILits> implements ISolver, UnitPropagationListener,
57 ActivityListener, Learner {
58
59 private static final long serialVersionUID = 1L;
60
61 private static final double CLAUSE_RESCALE_FACTOR = 1e-20;
62
63 private static final double CLAUSE_RESCALE_BOUND = 1 / CLAUSE_RESCALE_FACTOR;
64
65
66
67
68 private final IVec<Constr> constrs = new Vec<Constr>();
69
70
71
72
73 private final IVec<Constr> learnts = new Vec<Constr>();
74
75
76
77
78 private double claInc = 1.0;
79
80
81
82
83 private double claDecay = 1.0;
84
85
86
87
88
89
90 private int qhead = 0;
91
92
93
94
95
96
97 protected final IVecInt trail = new VecInt();
98
99
100
101
102
103
104 protected final IVecInt trailLim = new VecInt();
105
106
107
108
109
110
111 protected int rootLevel;
112
113 private int[] model = null;
114
115 protected L voc;
116
117 private IOrder<L> order;
118
119 private final ActivityComparator comparator = new ActivityComparator();
120
121 private final SolverStats stats = new SolverStats();
122
123 private final LearningStrategy<L> learner;
124
125 protected final AssertingClauseGenerator analyzer;
126
127 private boolean undertimeout;
128
129 private long timeout = Integer.MAX_VALUE;
130
131 protected DataStructureFactory<L> dsfactory;
132
133 private SearchParams params;
134
135 private final IVecInt __dimacs_out = new VecInt();
136
137 private SearchListener slistener = new NullSearchListener();
138
139 private RestartStrategy restarter;
140
141 protected IVecInt dimacs2internal(IVecInt in) {
142 if (voc.nVars() == 0) {
143 throw new RuntimeException(
144 "Please set the number of variables (solver.newVar() or solver.newVar(maxvar)) before adding constraints!");
145 }
146 __dimacs_out.clear();
147 __dimacs_out.ensure(in.size());
148 for (int i = 0; i < in.size(); i++) {
149 assert (in.get(i) != 0) && (Math.abs(in.get(i)) <= voc.nVars());
150 __dimacs_out.unsafePush(voc.getFromPool(in.get(i)));
151 }
152 return __dimacs_out;
153 }
154
155
156
157
158
159
160
161
162
163
164 public Solver(AssertingClauseGenerator acg, LearningStrategy<L> learner,
165 DataStructureFactory<L> dsf, IOrder<L> order, RestartStrategy restarter) {
166 this(acg, learner, dsf, new SearchParams(), order,restarter);
167 }
168
169 public Solver(AssertingClauseGenerator acg, LearningStrategy<L> learner,
170 DataStructureFactory<L> dsf, SearchParams params, IOrder<L> order, RestartStrategy restarter) {
171 analyzer = acg;
172 this.learner = learner;
173 this.order = order;
174 this.params = params;
175 setDataStructureFactory(dsf);
176 this.restarter = restarter;
177 }
178
179
180
181
182
183
184
185
186 public final void setDataStructureFactory(DataStructureFactory<L> dsf) {
187 dsfactory = dsf;
188 dsfactory.setUnitPropagationListener(this);
189 dsfactory.setLearner(this);
190 voc = dsf.getVocabulary();
191 order.setLits(voc);
192 }
193
194 public void setSearchListener(SearchListener sl) {
195 slistener = sl;
196 }
197
198 public void setTimeout(int t) {
199 timeout = t*1000L;
200 }
201
202 public void setTimeoutMs(long t) {
203 timeout = t;
204 }
205
206 public void setSearchParams(SearchParams sp) {
207 params = sp;
208 }
209
210 public void setRestartStrategy(RestartStrategy restarter) {
211 this.restarter = restarter;
212 }
213
214 protected int nAssigns() {
215 return trail.size();
216 }
217
218 public int nConstraints() {
219 return constrs.size();
220 }
221
222 public void learn(Constr c) {
223 learnts.push(c);
224 c.setLearnt();
225 c.register();
226 stats.learnedclauses++;
227 switch (c.size()) {
228 case 2:
229 stats.learnedbinaryclauses++;
230 break;
231 case 3:
232 stats.learnedternaryclauses++;
233 break;
234 default:
235
236 }
237 }
238
239 public int decisionLevel() {
240 return trailLim.size();
241 }
242
243 public int newVar() {
244 int index = voc.nVars() + 1;
245 voc.ensurePool(index);
246 mseen = new boolean[index + 1];
247 trail.ensure(index);
248 trailLim.ensure(index);
249 order.newVar();
250 return index;
251 }
252
253 public int newVar(int howmany) {
254 voc.ensurePool(howmany);
255 order.newVar(howmany);
256 mseen = new boolean[howmany + 1];
257 trail.ensure(howmany);
258 trailLim.ensure(howmany);
259 return voc.nVars();
260 }
261
262 public IConstr addClause(IVecInt literals) throws ContradictionException {
263 IVecInt vlits = dimacs2internal(literals);
264 return addConstr(dsfactory.createClause(vlits));
265 }
266
267 public boolean removeConstr(IConstr co) {
268 if (co == null) {
269 throw new UnsupportedOperationException(
270 "Reference to the constraint to remove needed!");
271 }
272 Constr c = (Constr) co;
273 c.remove();
274 constrs.remove(c);
275 clearLearntClauses();
276 cancelLearntLiterals();
277 return true;
278 }
279
280 public IConstr addPseudoBoolean(IVecInt literals, IVec<BigInteger> coeffs,
281 boolean moreThan, BigInteger degree) throws ContradictionException {
282 IVecInt vlits = dimacs2internal(literals);
283 assert vlits.size() == literals.size();
284 assert literals.size() == coeffs.size();
285 return addConstr(dsfactory.createPseudoBooleanConstraint(vlits, coeffs,
286 moreThan, degree));
287 }
288
289 public void addAllClauses(IVec<IVecInt> clauses)
290 throws ContradictionException {
291 for (IVecInt clause : clauses) {
292 addClause(clause);
293 }
294 }
295
296 public IConstr addAtMost(IVecInt literals, int degree)
297 throws ContradictionException {
298 int n = literals.size();
299 IVecInt opliterals = new VecInt(n);
300 for (int p : literals) {
301 opliterals.push(-p);
302 }
303 return addAtLeast(opliterals, n - degree);
304 }
305
306 public IConstr addAtLeast(IVecInt literals, int degree)
307 throws ContradictionException {
308 IVecInt vlits = dimacs2internal(literals);
309 return addConstr(dsfactory.createCardinalityConstraint(vlits, degree));
310 }
311
312 @SuppressWarnings("unchecked")
313 public boolean simplifyDB() {
314
315
316
317
318
319
320
321
322 IVec<Constr>[] cs = new IVec[] { constrs, learnts };
323 for (int type = 0; type < 2; type++) {
324 int j = 0;
325 for (int i = 0; i < cs[type].size(); i++) {
326 if (cs[type].get(i).simplify()) {
327
328 cs[type].get(i).remove();
329 } else {
330 cs[type].moveTo(j++, i);
331 }
332 }
333 cs[type].shrinkTo(j);
334 }
335 return true;
336 }
337
338
339
340
341
342
343 public int[] model() {
344 if (model == null) {
345 throw new UnsupportedOperationException(
346 "Call the solve method first!!!");
347 }
348 int[] nmodel = new int[model.length];
349 System.arraycopy(model, 0, nmodel, 0, model.length);
350 return nmodel;
351 }
352
353
354
355
356
357
358
359
360 public boolean enqueue(int p) {
361 return enqueue(p, null);
362 }
363
364
365
366
367
368
369
370
371
372
373
374 public boolean enqueue(int p, Constr from) {
375 assert p > 1;
376 if (voc.isSatisfied(p)) {
377
378 return true;
379 }
380 if (voc.isFalsified(p)) {
381
382 return false;
383 }
384
385 voc.satisfies(p);
386 voc.setLevel(p, decisionLevel());
387 voc.setReason(p, from);
388 trail.push(p);
389 return true;
390 }
391
392 private boolean[] mseen = new boolean[0];
393
394 private final IVecInt preason = new VecInt();
395
396 private final IVecInt outLearnt = new VecInt();
397
398 public int analyze(Constr confl, Handle<Constr> outLearntRef) {
399 assert confl != null;
400 outLearnt.clear();
401
402 final boolean[] seen = mseen;
403
404 assert outLearnt.size() == 0;
405 for (int i = 0; i < seen.length; i++) {
406 seen[i] = false;
407 }
408
409 analyzer.initAnalyze();
410 int p = ILits.UNDEFINED;
411
412 outLearnt.push(ILits.UNDEFINED);
413
414 int outBtlevel = 0;
415
416 do {
417 preason.clear();
418 assert confl != null;
419 confl.calcReason(p, preason);
420 if (confl.learnt())
421 claBumpActivity(confl);
422
423 for (int j = 0; j < preason.size(); j++) {
424 int q = preason.get(j);
425 order.updateVar(q);
426 if (!seen[q >> 1]) {
427
428 seen[q >> 1] = true;
429 if (voc.getLevel(q) == decisionLevel()) {
430 analyzer.onCurrentDecisionLevelLiteral(q);
431 } else if (voc.getLevel(q) > 0) {
432
433 outLearnt.push(q ^ 1);
434 outBtlevel = Math.max(outBtlevel, voc.getLevel(q));
435 }
436 }
437 }
438
439
440 do {
441 p = trail.last();
442
443
444 confl = voc.getReason(p);
445
446
447 undoOne();
448 } while (!seen[p >> 1]);
449
450
451 } while (analyzer.clauseNonAssertive(confl));
452
453 outLearnt.set(0, p ^ 1);
454 simplifier.simplify(outLearnt);
455
456 Constr c = dsfactory.createUnregisteredClause(outLearnt);
457 slistener.learn(c);
458
459 outLearntRef.obj = c;
460
461 assert outBtlevel > -1;
462 return outBtlevel;
463 }
464
465 interface ISimplifier extends Serializable {
466 void simplify(IVecInt outLearnt);
467 }
468
469 public static final ISimplifier NO_SIMPLIFICATION = new ISimplifier() {
470
471
472
473 private static final long serialVersionUID = 1L;
474
475 public void simplify(IVecInt outLearnt) {
476 }
477
478 @Override
479 public String toString() {
480 return "No reason simplification";
481 }
482 };
483
484 public final ISimplifier SIMPLE_SIMPLIFICATION = new ISimplifier() {
485
486
487
488 private static final long serialVersionUID = 1L;
489
490 public void simplify(IVecInt outLearnt) {
491 simpleSimplification(outLearnt);
492 }
493
494 @Override
495 public String toString() {
496 return "Simple reason simplification";
497 }
498 };
499
500 public final ISimplifier EXPENSIVE_SIMPLIFICATION = new ISimplifier() {
501
502
503
504
505 private static final long serialVersionUID = 1L;
506
507 public void simplify(IVecInt outLearnt) {
508 expensiveSimplification(outLearnt);
509 }
510
511 @Override
512 public String toString() {
513 return "Expensive reason simplification";
514 }
515 };
516
517 private ISimplifier simplifier = NO_SIMPLIFICATION;
518
519
520
521
522
523
524
525
526
527
528
529 public void setSimplifier(String simp) {
530 Field f;
531 try {
532 f = Solver.class.getDeclaredField(simp);
533 simplifier = (ISimplifier) f.get(this);
534 } catch (Exception e) {
535 e.printStackTrace();
536 simplifier = NO_SIMPLIFICATION;
537 }
538 }
539
540
541
542
543
544
545
546
547
548
549
550 public void setSimplifier(ISimplifier simp) {
551 simplifier = simp;
552 }
553
554
555 private void simpleSimplification(IVecInt outLearnt) {
556 int i, j;
557 final boolean[] seen = mseen;
558 for (i = j = 1; i < outLearnt.size(); i++) {
559 IConstr r = voc.getReason(outLearnt.get(i));
560 if (r == null) {
561 outLearnt.moveTo(j++, i);
562 } else {
563 assert r.get(0) == neg(outLearnt.get(i));
564 for (int k = 1; k < r.size(); k++)
565 if (!seen[r.get(k) >> 1] && (voc.getLevel(r.get(k)) != 0)) {
566 outLearnt.moveTo(j++, i);
567 break;
568 }
569 }
570 }
571 outLearnt.shrink(i - j);
572 stats.reducedliterals += (i - j);
573 }
574
575 private final IVecInt analyzetoclear = new VecInt();
576
577 private final IVecInt analyzestack = new VecInt();
578
579
580 private void expensiveSimplification(IVecInt outLearnt) {
581
582
583 int i, j;
584
585 analyzetoclear.clear();
586 outLearnt.copyTo(analyzetoclear);
587 for (i = 1, j = 1; i < outLearnt.size(); i++)
588 if (voc.getReason(outLearnt.get(i)) == null
589 || !analyzeRemovable(outLearnt.get(i)))
590 outLearnt.moveTo(j++, i);
591 outLearnt.shrink(i - j);
592 stats.reducedliterals += (i - j);
593 }
594
595
596
597
598 private boolean analyzeRemovable(int p) {
599 assert voc.getReason(p) != null;
600 analyzestack.clear();
601 analyzestack.push(p);
602 final boolean[] seen = mseen;
603 int top = analyzetoclear.size();
604 while (analyzestack.size() > 0) {
605 int q = analyzestack.last();
606 assert voc.getReason(q) != null;
607 Constr c = voc.getReason(q);
608 analyzestack.pop();
609 assert c.get(0) == neg(q);
610 for (int i = 1; i < c.size(); i++) {
611 int l = c.get(i);
612 if (!seen[var(l)] && voc.getLevel(l) != 0) {
613 if (voc.getReason(l) == null) {
614 for (int j = top; j < analyzetoclear.size(); j++)
615 seen[analyzetoclear.get(j) >> 1] = false;
616 analyzetoclear.shrink(analyzetoclear.size() - top);
617 return false;
618 }
619 seen[l >> 1] = true;
620 analyzestack.push(l);
621 analyzetoclear.push(l);
622 }
623 }
624 }
625
626 return true;
627 }
628
629
630
631
632
633
634
635
636 public static int decode2dimacs(int p) {
637 return ((p & 1) == 0 ? 1 : -1) * (p >> 1);
638 }
639
640
641
642
643 protected void undoOne() {
644
645 int p = trail.last();
646 assert p > 1;
647 assert voc.getLevel(p) >= 0;
648 int x = p >> 1;
649
650 voc.unassign(p);
651 voc.setReason(p, null);
652 voc.setLevel(p, -1);
653
654 order.undo(x);
655
656 trail.pop();
657
658
659
660 IVec<Undoable> undos = voc.undos(p);
661 assert undos != null;
662 while (undos.size() > 0) {
663 undos.last().undo(p);
664 undos.pop();
665 }
666 }
667
668
669
670
671
672
673
674 public void claBumpActivity(Constr confl) {
675 confl.incActivity(claInc);
676 if (confl.getActivity() > CLAUSE_RESCALE_BOUND)
677 claRescalActivity();
678
679
680
681 }
682
683 public void varBumpActivity(int p) {
684 order.updateVar(p);
685 }
686
687 private void claRescalActivity() {
688 for (int i = 0; i < learnts.size(); i++) {
689 learnts.get(i).rescaleBy(CLAUSE_RESCALE_FACTOR);
690 }
691 claInc *= CLAUSE_RESCALE_FACTOR;
692 }
693
694
695
696
697 public Constr propagate() {
698 while (qhead < trail.size()) {
699 stats.propagations++;
700 int p = trail.get(qhead++);
701 slistener.propagating(decode2dimacs(p));
702 order.assignLiteral(p);
703
704
705
706 assert p > 1;
707 IVec<Propagatable> constrs = dsfactory.getWatchesFor(p);
708
709 final int size = constrs.size();
710 for (int i = 0; i < size; i++) {
711 stats.inspects++;
712 if (!constrs.get(i).propagate(this, p)) {
713
714
715
716 dsfactory.conflictDetectedInWatchesFor(p, i);
717 qhead = trail.size();
718
719 return (Constr) constrs.get(i);
720 }
721 }
722 }
723 return null;
724 }
725
726 void record(Constr constr) {
727 constr.assertConstraint(this);
728 slistener.adding(decode2dimacs(constr.get(0)));
729 if (constr.size() == 1) {
730 stats.learnedliterals++;
731 } else {
732 learner.learns(constr);
733 }
734 }
735
736
737
738
739 public boolean assume(int p) {
740
741 assert trail.size() == qhead;
742 trailLim.push(trail.size());
743 return enqueue(p);
744 }
745
746
747
748
749 private void cancel() {
750
751 int decisionvar = trail.unsafeGet(trailLim.last());
752 slistener.backtracking(decode2dimacs(decisionvar));
753 for (int c = trail.size() - trailLim.last(); c > 0; c--) {
754 undoOne();
755 }
756 trailLim.pop();
757 }
758
759
760
761
762 private void cancelLearntLiterals() {
763
764
765 for (int c = trail.size() - rootLevel; c > 0; c--) {
766 undoOne();
767 }
768 qhead = trail.size();
769 }
770
771
772
773
774
775
776 protected void cancelUntil(int level) {
777 while (decisionLevel() > level) {
778 cancel();
779 }
780 qhead = trail.size();
781 }
782
783 private final Handle<Constr> learntConstraint = new Handle<Constr>();
784
785 private boolean[] fullmodel;
786
787 Lbool search(long nofConflicts) {
788 assert rootLevel == decisionLevel();
789 stats.starts++;
790 int conflictC = 0;
791
792
793 order.setVarDecay(1 / params.getVarDecay());
794 claDecay = 1 / params.getClaDecay();
795
796 do {
797 slistener.beginLoop();
798
799 Constr confl = propagate();
800 assert trail.size() == qhead;
801
802 if (confl == null) {
803
804
805
806
807
808
809
810
811
812
813
814
815 assert nAssigns() <= voc.realnVars();
816 if (nAssigns() == voc.realnVars()) {
817 slistener.solutionFound();
818 modelFound();
819 return Lbool.TRUE;
820 }
821 if (conflictC >= nofConflicts) {
822
823
824 cancelUntil(rootLevel);
825 return Lbool.UNDEFINED;
826 }
827 if (needToReduceDB) {
828 reduceDB();
829 needToReduceDB = false;
830
831 }
832
833 stats.decisions++;
834 int p = order.select();
835 assert p > 1;
836 slistener.assuming(decode2dimacs(p));
837 boolean ret = assume(p);
838 assert ret;
839 } else {
840
841 stats.conflicts++;
842 conflictC++;
843 slistener.conflictFound();
844 freeMem.newConflict();
845 if (decisionLevel() == rootLevel) {
846
847 return Lbool.FALSE;
848 }
849
850 int backtrackLevel = analyze(confl, learntConstraint);
851 assert backtrackLevel < decisionLevel();
852 cancelUntil(Math.max(backtrackLevel, rootLevel));
853 assert (decisionLevel() >= rootLevel)
854 && (decisionLevel() >= backtrackLevel);
855 if (learntConstraint.obj == null) {
856 return Lbool.FALSE;
857 }
858 record(learntConstraint.obj);
859 learntConstraint.obj = null;
860 decayActivities();
861 }
862 } while (undertimeout);
863 return Lbool.UNDEFINED;
864 }
865
866
867
868
869 void modelFound() {
870 model = new int[trail.size()];
871 fullmodel = new boolean[nVars()];
872 int index = 0;
873 for (int i = 1; i <= voc.nVars(); i++) {
874 if (voc.belongsToPool(i)) {
875 int p = voc.getFromPool(i);
876 if (!voc.isUnassigned(p)) {
877 model[index++] = voc.isSatisfied(p) ? i : -i;
878 fullmodel[i - 1] = voc.isSatisfied(p);
879 }
880 }
881 }
882 assert index == model.length;
883 cancelUntil(rootLevel);
884 }
885
886 public boolean model(int var) {
887 if (var <= 0 || var > nVars()) {
888 throw new IllegalArgumentException(
889 "Use a valid Dimacs var id as argument!");
890 }
891 if (fullmodel == null) {
892 throw new UnsupportedOperationException(
893 "Call the solve method first!!!");
894 }
895 return fullmodel[var - 1];
896 }
897
898
899
900
901 protected void reduceDB() {
902 reduceDB(claInc / learnts.size());
903 }
904
905 public void clearLearntClauses() {
906 for (Constr c : learnts)
907 c.remove();
908 learnts.clear();
909 }
910
911 protected void reduceDB(double lim) {
912 int i, j;
913 sortOnActivity();
914 stats.reduceddb++;
915 for (i = j = 0; i < learnts.size() / 2; i++) {
916 Constr c = learnts.get(i);
917 if (c.locked()) {
918 learnts.set(j++, learnts.get(i));
919 } else {
920 c.remove();
921 }
922 }
923 for (; i < learnts.size(); i++) {
924
925
926
927
928 learnts.set(j++, learnts.get(i));
929
930 }
931 System.out.println("c cleaning " + (learnts.size() - j)
932 + " clauses out of " + learnts.size() + " for limit " + lim);
933 learnts.shrinkTo(j);
934 }
935
936
937
938
939 private void sortOnActivity() {
940 learnts.sort(comparator);
941 }
942
943
944
945
946 protected void decayActivities() {
947 order.varDecayActivity();
948 claDecayActivity();
949 }
950
951
952
953
954 private void claDecayActivity() {
955 claInc *= claDecay;
956 }
957
958
959
960
961 public boolean isSatisfiable() throws TimeoutException {
962 return isSatisfiable(VecInt.EMPTY);
963 }
964
965 private double timebegin = 0;
966
967 private boolean needToReduceDB;
968
969 private ConflictTimer freeMem;
970
971 public boolean isSatisfiable(IVecInt assumps) throws TimeoutException {
972 Lbool status = Lbool.UNDEFINED;
973
974 order.init();
975 learner.init();
976 restarter.init(params);
977 timebegin = System.currentTimeMillis();
978 slistener.start();
979 model = null;
980 fullmodel = null;
981
982
983 if (propagate() != null) {
984 slistener.end(Lbool.FALSE);
985 cancelUntil(0);
986 return false;
987 }
988
989
990 for (int q : assumps) {
991 if (!assume(voc.getFromPool(q)) || (propagate() != null)) {
992 slistener.end(Lbool.FALSE);
993 cancelUntil(0);
994 return false;
995 }
996 }
997 rootLevel = decisionLevel();
998
999 TimerTask stopMe = new TimerTask() {
1000 @Override
1001 public void run() {
1002 undertimeout = false;
1003 }
1004 };
1005 undertimeout = true;
1006 Timer timer = new Timer(true);
1007 timer.schedule(stopMe, timeout);
1008 needToReduceDB = false;
1009
1010 final long memorybound = Runtime.getRuntime().freeMemory() / 10;
1011 freeMem = new ConflictTimer(500) {
1012 private static final long serialVersionUID = 1L;
1013 @Override
1014 void run() {
1015 long freemem = Runtime.getRuntime().freeMemory();
1016
1017 if (freemem < memorybound) {
1018
1019 needToReduceDB = true;
1020 }
1021 }
1022 };
1023
1024 while ((status == Lbool.UNDEFINED) && undertimeout) {
1025 status = search(restarter.nextRestartNumberOfConflict());
1026
1027 restarter.onRestart();
1028 }
1029
1030 cancelUntil(0);
1031 timer.cancel();
1032 slistener.end(status);
1033 if (!undertimeout) {
1034 throw new TimeoutException(" Timeout (" + timeout + "s) exceeded");
1035 }
1036 return status == Lbool.TRUE;
1037 }
1038
1039 public SolverStats getStats() {
1040 return stats;
1041 }
1042
1043 public IOrder<L> getOrder() {
1044 return order;
1045 }
1046
1047 public void setOrder(IOrder<L> h) {
1048 order = h;
1049 order.setLits(voc);
1050 }
1051
1052 public L getVocabulary() {
1053 return voc;
1054 }
1055
1056 public void reset() {
1057
1058 voc.resetPool();
1059 dsfactory.reset();
1060 constrs.clear();
1061 learnts.clear();
1062 stats.reset();
1063 }
1064
1065 public int nVars() {
1066 return voc.nVars();
1067 }
1068
1069
1070
1071
1072
1073
1074 protected IConstr addConstr(Constr constr) {
1075 if (constr != null) {
1076 constrs.push(constr);
1077 }
1078 return constr;
1079 }
1080
1081 public DataStructureFactory<L> getDSFactory() {
1082 return dsfactory;
1083 }
1084
1085 public IVecInt getOutLearnt() {
1086 return outLearnt;
1087 }
1088
1089
1090
1091
1092
1093
1094
1095
1096 public IConstr getIthConstr(int i) {
1097 return constrs.get(i);
1098 }
1099
1100
1101
1102
1103
1104
1105
1106 public void printStat(PrintStream out, String prefix) {
1107 printStat(new PrintWriter(out), prefix);
1108 }
1109
1110 public void printStat(PrintWriter out, String prefix) {
1111 stats.printStat(out, prefix);
1112 double cputime = (System.currentTimeMillis() - timebegin) / 1000;
1113 out.println(prefix + "speed (decisions/second)\t: " + stats.decisions
1114 / cputime);
1115 order.printStat(out, prefix);
1116 }
1117
1118
1119
1120
1121
1122
1123 public String toString(String prefix) {
1124 StringBuilder stb = new StringBuilder();
1125 Object[] objs = { analyzer, dsfactory, learner, params, order,
1126 simplifier, restarter };
1127
1128 stb.append("--- Begin Solver configuration ---");
1129 stb.append("\n");
1130 for (Object o : objs) {
1131 stb.append(prefix);
1132 stb.append(o.toString());
1133 stb.append("\n");
1134 }
1135 stb.append(prefix);
1136 stb.append("--- End Solver configuration ---");
1137 return stb.toString();
1138 }
1139
1140
1141
1142
1143
1144
1145 @Override
1146 public String toString() {
1147 return toString("");
1148 }
1149
1150 public int getTimeout() {
1151 return (int)(timeout/1000);
1152 }
1153
1154 public void setExpectedNumberOfClauses(int nb) {
1155 constrs.ensure(nb);
1156 }
1157
1158 public Map<String, Number> getStat() {
1159 return stats.toMap();
1160 }
1161
1162 public int[] findModel() throws TimeoutException {
1163 if (isSatisfiable()) {
1164 return model();
1165 }
1166
1167
1168 return null;
1169 }
1170
1171 public int[] findModel(IVecInt assumps) throws TimeoutException {
1172 if (isSatisfiable(assumps)) {
1173 return model();
1174 }
1175
1176
1177 return null;
1178 }
1179
1180 }
1181
1182 class ActivityComparator implements Comparator<Constr>, Serializable {
1183
1184 private static final long serialVersionUID = 1L;
1185
1186
1187
1188
1189
1190
1191 public int compare(Constr c1, Constr c2) {
1192 return (int) Math.round(c1.getActivity() - c2.getActivity());
1193 }
1194 }
1195
1196 abstract class ConflictTimer implements Serializable {
1197
1198 private int counter;
1199 private final int bound;
1200
1201 ConflictTimer(final int bound) {
1202 this.bound = bound;
1203 counter = 0;
1204 }
1205
1206 void reset() {
1207 counter = 0;
1208 }
1209
1210 void newConflict() {
1211 counter++;
1212 if (counter==bound) {
1213 run();
1214 counter = 0;
1215 }
1216 }
1217
1218 abstract void run();
1219 }