ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
Solver.cpp
Go to the documentation of this file.
1/***************************************************************************************[Solver.cc]
2Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
3Copyright (c) 2007-2010, Niklas Sorensson
4
5Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6associated documentation files (the "Software"), to deal in the Software without restriction,
7including without limitation the rights to use, copy, modify, merge, publish, distribute,
8sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all copies or
12substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19**************************************************************************************************/
20
21#include <math.h>
22
23#include "sat/bsat2/Sort.h"
24#include "sat/bsat2/Solver.h"
25
27
28using namespace Minisat;
29
30//=================================================================================================
31// Options:
32
33
34static const char* _cat = "CORE";
35
36static DoubleOption opt_var_decay (_cat, "var-decay", "The variable activity decay factor", 0.95, DoubleRange(0, false, 1, false));
37static DoubleOption opt_clause_decay (_cat, "cla-decay", "The clause activity decay factor", 0.999, DoubleRange(0, false, 1, false));
38static DoubleOption opt_random_var_freq (_cat, "rnd-freq", "The frequency with which the decision heuristic tries to choose a random variable", 0, DoubleRange(0, true, 1, true));
39static DoubleOption opt_random_seed (_cat, "rnd-seed", "Used by the random variable selection", 91648253, DoubleRange(0, false, HUGE_VAL, false));
40static IntOption opt_ccmin_mode (_cat, "ccmin-mode", "Controls conflict clause minimization (0=none, 1=basic, 2=deep)", 2, IntRange(0, 2));
41static IntOption opt_phase_saving (_cat, "phase-saving", "Controls the level of phase saving (0=none, 1=limited, 2=full)", 2, IntRange(0, 2));
42static BoolOption opt_rnd_init_act (_cat, "rnd-init", "Randomize the initial activity", false);
43static BoolOption opt_luby_restart (_cat, "luby", "Use the Luby restart sequence", true);
44static IntOption opt_restart_first (_cat, "rfirst", "The base restart interval", 100, IntRange(1, INT32_MAX));
45static DoubleOption opt_restart_inc (_cat, "rinc", "Restart interval increase factor", 2, DoubleRange(1, false, HUGE_VAL, false));
46static DoubleOption opt_garbage_frac (_cat, "gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered", 0.20, DoubleRange(0, false, HUGE_VAL, false));
47
48
49//=================================================================================================
50// Constructor/Destructor:
51
52
54
55 // Parameters (user settable):
56 //
57 verbosity (0)
58 , var_decay (opt_var_decay)
59 , clause_decay (opt_clause_decay)
60 , random_var_freq (opt_random_var_freq)
61 , random_seed (opt_random_seed)
62 , luby_restart (opt_luby_restart)
63 , ccmin_mode (opt_ccmin_mode)
64 , phase_saving (opt_phase_saving)
65 , rnd_pol (false)
66 , rnd_init_act (opt_rnd_init_act)
67 , garbage_frac (opt_garbage_frac)
68 , restart_first (opt_restart_first)
69 , restart_inc (opt_restart_inc)
70
71 // Parameters (the rest):
72 //
73 , learntsize_factor((double)1/(double)3), learntsize_inc(1.1)
74
75 // Parameters (experimental):
76 //
79
80 // Statistics: (formerly in 'SolverStats')
81 //
84
85 , ok (true)
86 , cla_inc (1)
87 , var_inc (1)
89 , qhead (0)
90 , simpDB_assigns (-1)
91 , simpDB_props (0)
95
96 // Resource constraints:
97 //
98 , conflict_budget (-1)
101{}
102
103
105{
106}
107
108
109//=================================================================================================
110// Minor methods:
111
112
113// Creates a new SAT variable in the solver. If 'decision' is cleared, variable will not be
114// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result).
115//
116Var Solver::newVar(bool sign, bool dvar)
117{
118 int v = nVars();
119 watches .init(mkLit(v, false));
120 watches .init(mkLit(v, true ));
121 assigns .push(l_Undef);
122 vardata .push(mkVarData(CRef_Undef, 0));
123 //activity .push(0);
124 activity .push(rnd_init_act ? drand(random_seed) * 0.00001 : 0);
125 seen .push(0);
126 polarity .push(sign);
127 decision .push();
128 trail .capacity(v+1);
129 setDecisionVar(v, dvar);
130 return v;
131}
132
133
135{
136 assert(decisionLevel() == 0);
137 if (!ok) return false;
138
139 // Check if clause is satisfied and remove false/duplicate literals:
140 sort(ps);
141 Lit p; int i, j;
142 for (i = j = 0, p = lit_Undef; i < ps.size(); i++)
143 if (value(ps[i]) == l_True || ps[i] == ~p)
144 return true;
145 else if (value(ps[i]) != l_False && ps[i] != p)
146 ps[j++] = p = ps[i];
147 ps.shrink(i - j);
148
149 if (ps.size() == 0)
150 return ok = false;
151 else if (ps.size() == 1){
152 uncheckedEnqueue(ps[0]);
153 return ok = (propagate() == CRef_Undef);
154 }else{
155 CRef cr = ca.alloc(ps, false);
156 clauses.push(cr);
157 attachClause(cr);
158 }
159
160 return true;
161}
162
163
165 const Clause& c = ca[cr];
166 assert(c.size() > 1);
167 watches[~c[0]].push(Watcher(cr, c[1]));
168 watches[~c[1]].push(Watcher(cr, c[0]));
169 if (c.learnt()) learnts_literals += c.size();
170 else clauses_literals += c.size(); }
171
172
173void Solver::detachClause(CRef cr, bool strict) {
174 const Clause& c = ca[cr];
175 assert(c.size() > 1);
176
177 if (strict){
178 remove(watches[~c[0]], Watcher(cr, c[1]));
179 remove(watches[~c[1]], Watcher(cr, c[0]));
180 }else{
181 // Lazy detaching: (NOTE! Must clean all watcher lists before garbage collecting this clause)
182 watches.smudge(~c[0]);
183 watches.smudge(~c[1]);
184 }
185
186 if (c.learnt()) learnts_literals -= c.size();
187 else clauses_literals -= c.size(); }
188
189
191 Clause& c = ca[cr];
192 detachClause(cr);
193 // Don't leave pointers to free'd memory!
194 if (locked(c)) vardata[var(c[0])].reason = CRef_Undef;
195 c.mark(1);
196 ca._free(cr);
197}
198
199
200bool Solver::satisfied(const Clause& c) const {
201 for (int i = 0; i < c.size(); i++)
202 if (value(c[i]) == l_True)
203 return true;
204 return false; }
205
206
207// Revert to the state at given level (keeping all assignment at 'level' but not beyond).
208//
210 if (decisionLevel() > level){
211 for (int c = trail.size()-1; c >= trail_lim[level]; c--){
212 Var x = var(trail[c]);
213 assigns [x] = l_Undef;
214 if (phase_saving > 1 || ((phase_saving == 1) && c > trail_lim.last()))
215 polarity[x] = sign(trail[c]);
216 insertVarOrder(x); }
218 trail.shrink(trail.size() - trail_lim[level]);
219 trail_lim.shrink(trail_lim.size() - level);
220 } }
221
222
223//=================================================================================================
224// Major methods:
225
226
228{
229 Var next = var_Undef;
230
231 // Random decision:
232 if (drand(random_seed) < random_var_freq && !order_heap.empty()){
233 next = order_heap[irand(random_seed,order_heap.size())];
234 if (value(next) == l_Undef && decision[next])
235 rnd_decisions++; }
236
237 // Activity based decision:
238 while (next == var_Undef || value(next) != l_Undef || !decision[next])
239 if (order_heap.empty()){
240 next = var_Undef;
241 break;
242 }else
243 next = order_heap.removeMin();
244
245 return next == var_Undef ? lit_Undef : mkLit(next, rnd_pol ? drand(random_seed) < 0.5 : polarity[next]);
246}
247
248
249/*_________________________________________________________________________________________________
250|
251| analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&) -> [void]
252|
253| Description:
254| Analyze conflict and produce a reason clause.
255|
256| Pre-conditions:
257| * 'out_learnt' is assumed to be cleared.
258| * Current decision level must be greater than root level.
259|
260| Post-conditions:
261| * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
262| * If out_learnt.size() > 1 then 'out_learnt[1]' has the greatest decision level of the
263| rest of literals. There may be others from the same level though.
264|
265|________________________________________________________________________________________________@*/
266void Solver::analyze(CRef confl, vec<Lit>& out_learnt, int& out_btlevel)
267{
268 int pathC = 0;
269 Lit p = lit_Undef;
270
271 // Generate conflict clause:
272 //
273 out_learnt.push(); // (leave room for the asserting literal)
274 int index = trail.size() - 1;
275
276 do{
277 assert(confl != CRef_Undef); // (otherwise should be UIP)
278 Clause& c = ca[confl];
279
280 if (c.learnt())
282
283 for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
284 Lit q = c[j];
285
286 if (!seen[var(q)] && level(var(q)) > 0){
288 seen[var(q)] = 1;
289 if (level(var(q)) >= decisionLevel())
290 pathC++;
291 else
292 out_learnt.push(q);
293 }
294 }
295
296 // Select next clause to look at:
297 while (!seen[var(trail[index--])]);
298 p = trail[index+1];
299 confl = reason(var(p));
300 seen[var(p)] = 0;
301 pathC--;
302
303 }while (pathC > 0);
304 out_learnt[0] = ~p;
305
306 // Simplify conflict clause:
307 //
308 int i, j;
309 out_learnt.copyTo(analyze_toclear);
310 if (ccmin_mode == 2){
311 uint32_t abstract_level = 0;
312 for (i = 1; i < out_learnt.size(); i++)
313 abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict)
314
315 for (i = j = 1; i < out_learnt.size(); i++)
316 if (reason(var(out_learnt[i])) == CRef_Undef || !litRedundant(out_learnt[i], abstract_level))
317 out_learnt[j++] = out_learnt[i];
318
319 }else if (ccmin_mode == 1){
320 for (i = j = 1; i < out_learnt.size(); i++){
321 Var x = var(out_learnt[i]);
322
323 if (reason(x) == CRef_Undef)
324 out_learnt[j++] = out_learnt[i];
325 else{
326 Clause& c = ca[reason(var(out_learnt[i]))];
327 for (int k = 1; k < c.size(); k++)
328 if (!seen[var(c[k])] && level(var(c[k])) > 0){
329 out_learnt[j++] = out_learnt[i];
330 break; }
331 }
332 }
333 }else
334 i = j = out_learnt.size();
335
336 max_literals += out_learnt.size();
337 out_learnt.shrink(i - j);
338 tot_literals += out_learnt.size();
339
340 // Find correct backtrack level:
341 //
342 if (out_learnt.size() == 1)
343 out_btlevel = 0;
344 else{
345 int max_i = 1;
346 // Find the first literal assigned at the next-highest level:
347 for (int i = 2; i < out_learnt.size(); i++)
348 if (level(var(out_learnt[i])) > level(var(out_learnt[max_i])))
349 max_i = i;
350 // Swap-in this literal at index 1:
351 Lit p = out_learnt[max_i];
352 out_learnt[max_i] = out_learnt[1];
353 out_learnt[1] = p;
354 out_btlevel = level(var(p));
355 }
356
357 for (j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared)
358}
359
360
361// Check if 'p' can be removed. 'abstract_levels' is used to abort early if the algorithm is
362// visiting literals at levels that cannot be removed later.
363bool Solver::litRedundant(Lit p, uint32_t abstract_levels)
364{
365 analyze_stack.clear(); analyze_stack.push(p);
366 int top = analyze_toclear.size();
367 while (analyze_stack.size() > 0){
369 Clause& c = ca[reason(var(analyze_stack.last()))]; analyze_stack.pop();
370
371 for (int i = 1; i < c.size(); i++){
372 Lit p = c[i];
373 if (!seen[var(p)] && level(var(p)) > 0){
374 if (reason(var(p)) != CRef_Undef && (abstractLevel(var(p)) & abstract_levels) != 0){
375 seen[var(p)] = 1;
376 analyze_stack.push(p);
377 analyze_toclear.push(p);
378 }else{
379 for (int j = top; j < analyze_toclear.size(); j++)
380 seen[var(analyze_toclear[j])] = 0;
381 analyze_toclear.shrink(analyze_toclear.size() - top);
382 return false;
383 }
384 }
385 }
386 }
387
388 return true;
389}
390
391
392/*_________________________________________________________________________________________________
393|
394| analyzeFinal : (p : Lit) -> [void]
395|
396| Description:
397| Specialized analysis procedure to express the final conflict in terms of assumptions.
398| Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and
399| stores the result in 'out_conflict'.
400|________________________________________________________________________________________________@*/
401void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
402{
403 out_conflict.clear();
404 out_conflict.push(p);
405
406 if (decisionLevel() == 0)
407 return;
408
409 seen[var(p)] = 1;
410
411 for (int i = trail.size()-1; i >= trail_lim[0]; i--){
412 Var x = var(trail[i]);
413 if (seen[x]){
414 if (reason(x) == CRef_Undef){
415 assert(level(x) > 0);
416 out_conflict.push(~trail[i]);
417 }else{
418 Clause& c = ca[reason(x)];
419 for (int j = 1; j < c.size(); j++)
420 if (level(var(c[j])) > 0)
421 seen[var(c[j])] = 1;
422 }
423 seen[x] = 0;
424 }
425 }
426
427 seen[var(p)] = 0;
428}
429
430
432{
433 assert(value(p) == l_Undef);
434 assigns[var(p)] = lbool(!sign(p));
435 vardata[var(p)] = mkVarData(from, decisionLevel());
436 trail.push_(p);
437}
438
439
440/*_________________________________________________________________________________________________
441|
442| propagate : [void] -> [Clause*]
443|
444| Description:
445| Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
446| otherwise CRef_Undef.
447|
448| Post-conditions:
449| * the propagation queue is empty, even if there was a conflict.
450|________________________________________________________________________________________________@*/
452{
453 CRef confl = CRef_Undef;
454 int num_props = 0;
455 watches.cleanAll();
456
457 while (qhead < trail.size()){
458 Lit p = trail[qhead++]; // 'p' is enqueued fact to propagate.
459 vec<Watcher>& ws = watches[p];
460 Watcher *i, *j, *end;
461 num_props++;
462
463 for (i = j = (Watcher*)ws, end = i + ws.size(); i != end;){
464 // Try to avoid inspecting the clause:
465 Lit blocker = i->blocker;
466 if (value(blocker) == l_True){
467 *j++ = *i++; continue; }
468
469 // Make sure the false literal is data[1]:
470 CRef cr = i->cref;
471 Clause& c = ca[cr];
472 Lit false_lit = ~p;
473 if (c[0] == false_lit)
474 c[0] = c[1], c[1] = false_lit;
475 assert(c[1] == false_lit);
476 i++;
477
478 // If 0th watch is true, then clause is already satisfied.
479 Lit first = c[0];
480 Watcher w = Watcher(cr, first);
481 if (first != blocker && value(first) == l_True){
482 *j++ = w; continue; }
483
484 // Look for new watch:
485 for (int k = 2; k < c.size(); k++)
486 if (value(c[k]) != l_False){
487 c[1] = c[k]; c[k] = false_lit;
488 watches[~c[1]].push(w);
489 goto NextClause; }
490
491 // Did not find watch -- clause is unit under assignment:
492 *j++ = w;
493 if (value(first) == l_False){
494 confl = cr;
495 qhead = trail.size();
496 // Copy the remaining watches:
497 while (i < end)
498 *j++ = *i++;
499 }else
500 uncheckedEnqueue(first, cr);
501
502 NextClause:;
503 }
504 ws.shrink(i - j);
505 }
506 propagations += num_props;
507 simpDB_props -= num_props;
508
509 return confl;
510}
511
512
513/*_________________________________________________________________________________________________
514|
515| reduceDB : () -> [void]
516|
517| Description:
518| Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked
519| clauses are clauses that are reason to some assignment. Binary clauses are never removed.
520|________________________________________________________________________________________________@*/
521struct reduceDB_lt {
524 bool operator () (CRef x, CRef y) {
525 return ca[x].size() > 2 && (ca[y].size() == 2 || ca[x].activity() < ca[y].activity()); }
526};
528{
529 int i, j;
530 double extra_lim = cla_inc / learnts.size(); // Remove any clause below this activity
531
533 // Don't delete binary or locked clauses. From the rest, delete clauses from the first half
534 // and clauses with activity smaller than 'extra_lim':
535 for (i = j = 0; i < learnts.size(); i++){
536 Clause& c = ca[learnts[i]];
537 if (c.size() > 2 && !locked(c) && (i < learnts.size() / 2 || c.activity() < extra_lim))
539 else
540 learnts[j++] = learnts[i];
541 }
542 learnts.shrink(i - j);
543 checkGarbage();
544}
545
546
548{
549 int i, j;
550 for (i = j = 0; i < cs.size(); i++){
551 Clause& c = ca[cs[i]];
552 if (satisfied(c))
553 removeClause(cs[i]);
554 else
555 cs[j++] = cs[i];
556 }
557 cs.shrink(i - j);
558}
559
560
562{
563 vec<Var> vs;
564 for (Var v = 0; v < nVars(); v++)
565 if (decision[v] && value(v) == l_Undef)
566 vs.push(v);
567 order_heap.build(vs);
568}
569
570
571/*_________________________________________________________________________________________________
572|
573| simplify : [void] -> [bool]
574|
575| Description:
576| Simplify the clause database according to the current top-level assigment. Currently, the only
577| thing done here is the removal of satisfied clauses, but more things can be put here.
578|________________________________________________________________________________________________@*/
580{
581 assert(decisionLevel() == 0);
582
583 if (!ok || propagate() != CRef_Undef)
584 return ok = false;
585
586 if (nAssigns() == simpDB_assigns || (simpDB_props > 0))
587 return true;
588
589 // Remove satisfied clauses:
591 if (remove_satisfied) // Can be turned off.
593 checkGarbage();
595
597 simpDB_props = clauses_literals + learnts_literals; // (shouldn't depend on stats really, but it will do for now)
598
599 return true;
600}
601
602
603/*_________________________________________________________________________________________________
604|
605| search : (nof_conflicts : int) (params : const SearchParams&) -> [lbool]
606|
607| Description:
608| Search for a model the specified number of conflicts.
609| NOTE! Use negative value for 'nof_conflicts' indicate infinity.
610|
611| Output:
612| 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If
613| all variables are decision variables, this means that the clause set is satisfiable. 'l_False'
614| if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.
615|________________________________________________________________________________________________@*/
616lbool Solver::search(int nof_conflicts)
617{
618 assert(ok);
619 int backtrack_level;
620 int conflictC = 0;
621 vec<Lit> learnt_clause;
622 starts++;
623
624 for (;;){
625 CRef confl = propagate();
626 if (confl != CRef_Undef){
627 // CONFLICT
628 conflicts++; conflictC++;
629 if (decisionLevel() == 0) return l_False;
630
631 learnt_clause.clear();
632 analyze(confl, learnt_clause, backtrack_level);
633 cancelUntil(backtrack_level);
634
635 if (learnt_clause.size() == 1){
636 uncheckedEnqueue(learnt_clause[0]);
637 }else{
638 CRef cr = ca.alloc(learnt_clause, true);
639 learnts.push(cr);
640 attachClause(cr);
641 claBumpActivity(ca[cr]);
642 uncheckedEnqueue(learnt_clause[0], cr);
643 }
644
647
648 if (--learntsize_adjust_cnt == 0){
652
653 if (verbosity >= 1)
654 printf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n",
655 (int)conflicts,
656 (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]), nClauses(), (int)clauses_literals,
657 (int)max_learnts, nLearnts(), ((double)((int64_t)learnts_literals))/nLearnts(), progressEstimate()*100);
658 }
659
660 }else{
661 // NO CONFLICT
662 if ( (nof_conflicts >= 0 && conflictC >= nof_conflicts) || !withinBudget()){
663 // Reached bound on number of conflicts:
665 cancelUntil(0);
666 return l_Undef; }
667
668 // Simplify the set of problem clauses:
669 if (decisionLevel() == 0 && !simplify())
670 return l_False;
671
672 if (learnts.size()-nAssigns() >= max_learnts)
673 // Reduce the set of learnt clauses:
674 reduceDB();
675
676 Lit next = lit_Undef;
677 while (decisionLevel() < assumptions.size()){
678 // Perform user provided assumption:
680 if (value(p) == l_True){
681 // Dummy decision level:
683 }else if (value(p) == l_False){
685 return l_False;
686 }else{
687 next = p;
688 break;
689 }
690 }
691
692 if (next == lit_Undef){
693 // New variable decision:
694 decisions++;
695 next = pickBranchLit();
696
697 if (next == lit_Undef)
698 // Model found:
699 return l_True;
700 }
701
702 // Increase decision level and enqueue 'next'
704 uncheckedEnqueue(next);
705 }
706 }
707}
708
709
711{
712 double progress = 0;
713 double F = 1.0 / nVars();
714
715 for (int i = 0; i <= decisionLevel(); i++){
716 int beg = i == 0 ? 0 : trail_lim[i - 1];
717 int end = i == decisionLevel() ? trail.size() : trail_lim[i];
718 progress += pow(F, i) * (end - beg);
719 }
720
721 return progress / nVars();
722}
723
724/*
725 Finite subsequences of the Luby-sequence:
726
727 0: 1
728 1: 1 1 2
729 2: 1 1 2 1 1 2 4
730 3: 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8
731 ...
732
733
734 */
735
736static double luby(double y, int x){
737
738 // Find the finite subsequence that contains index 'x', and the
739 // size of that subsequence:
740 int size, seq;
741 for (size = 1, seq = 0; size < x+1; seq++, size = 2*size+1);
742
743 while (size-1 != x){
744 size = (size-1)>>1;
745 seq--;
746 x = x % size;
747 }
748
749 return pow(y, seq);
750}
751
752// NOTE: assumptions passed in member-variable 'assumptions'.
754{
755 model.clear();
756 conflict.clear();
757 if (!ok) return l_False;
758
759 solves++;
760
764 lbool status = l_Undef;
765
766 if (verbosity >= 1){
767 printf("============================[ Search Statistics ]==============================\n");
768 printf("| Conflicts | ORIGINAL | LEARNT | Progress |\n");
769 printf("| | Vars Clauses Literals | Limit Clauses Lit/Cl | |\n");
770 printf("===============================================================================\n");
771 }
772
773 // Search:
774 int curr_restarts = 0;
775 while (status == l_Undef){
776 double rest_base = luby_restart ? luby(restart_inc, curr_restarts) : pow(restart_inc, curr_restarts);
777 status = search(rest_base * restart_first);
778 if (!withinBudget()) break;
779 curr_restarts++;
780 }
781
782 if (verbosity >= 1)
783 printf("===============================================================================\n");
784
785
786 if (status == l_True){
787 // Extend & copy model:
788 model.growTo(nVars());
789 for (int i = 0; i < nVars(); i++) model[i] = value(i);
790 }else if (status == l_False && conflict.size() == 0)
791 ok = false;
792
793 cancelUntil(0);
794 return status;
795}
796
797//=================================================================================================
798// Writing CNF to DIMACS:
799//
800// FIXME: this needs to be rewritten completely.
801
802static Var mapVar(Var x, vec<Var>& map, Var& max)
803{
804 if (map.size() <= x || map[x] == -1){
805 map.growTo(x+1, -1);
806 map[x] = max++;
807 }
808 return map[x];
809}
810
811
812void Solver::toDimacs(FILE* f, Clause& c, vec<Var>& map, Var& max)
813{
814 if (satisfied(c)) return;
815
816 for (int i = 0; i < c.size(); i++)
817 if (value(c[i]) != l_False)
818 fprintf(f, "%s%d ", sign(c[i]) ? "-" : "", mapVar(var(c[i]), map, max)+1);
819 fprintf(f, "0\n");
820}
821
822
823void Solver::toDimacs(const char *file, const vec<Lit>& assumps)
824{
825 FILE* f = fopen(file, "wb");
826 if (f == NULL)
827 fprintf(stderr, "could not open file %s\n", file), exit(1);
828 toDimacs(f, assumps);
829 fclose(f);
830}
831
832
833void Solver::toDimacs(FILE* f, const vec<Lit>& assumps)
834{
835 // Handle case when solver is in contradictory state:
836 if (!ok){
837 fprintf(f, "p cnf 1 2\n1 0\n-1 0\n");
838 return; }
839
840 vec<Var> map; Var max = 0;
841
842 // Cannot use removeClauses here because it is not safe
843 // to deallocate them at this point. Could be improved.
844 int i, cnt = 0;
845 for (i = 0; i < clauses.size(); i++)
846 if (!satisfied(ca[clauses[i]]))
847 cnt++;
848
849 for (i = 0; i < clauses.size(); i++)
850 if (!satisfied(ca[clauses[i]])){
851 Clause& c = ca[clauses[i]];
852 for (int j = 0; j < c.size(); j++)
853 if (value(c[j]) != l_False)
854 mapVar(var(c[j]), map, max);
855 }
856
857 // Assumptions are added as unit clauses:
858 cnt += assumptions.size();
859
860 fprintf(f, "p cnf %d %d\n", max, cnt);
861
862 for (i = 0; i < assumptions.size(); i++){
864 fprintf(f, "%s%d 0\n", sign(assumptions[i]) ? "-" : "", mapVar(var(assumptions[i]), map, max)+1);
865 }
866
867 for (i = 0; i < clauses.size(); i++)
868 toDimacs(f, ca[clauses[i]], map, max);
869
870 if (verbosity > 0)
871 printf("Wrote %d clauses with %d variables.\n", cnt, max);
872}
873
874
875//=================================================================================================
876// Garbage Collection methods:
877
879{
880 // All watchers:
881 //
882 // for (int i = 0; i < watches.size(); i++)
883 watches.cleanAll();
884 for (int v = 0; v < nVars(); v++)
885 for (int s = 0; s < 2; s++){
886 Lit p = mkLit(v, s);
887 // printf(" >>> RELOCING: %s%d\n", sign(p)?"-":"", var(p)+1);
888 vec<Watcher>& ws = watches[p];
889 for (int j = 0; j < ws.size(); j++)
890 ca.reloc(ws[j].cref, to);
891 }
892
893 // All reasons:
894 //
895 int i;
896 for (i = 0; i < trail.size(); i++){
897 Var v = var(trail[i]);
898
899 if (reason(v) != CRef_Undef && (ca[reason(v)].reloced() || locked(ca[reason(v)])))
900 ca.reloc(vardata[v].reason, to);
901 }
902
903 // All learnt:
904 //
905 for (i = 0; i < learnts.size(); i++)
906 ca.reloc(learnts[i], to);
907
908 // All original:
909 //
910 for (i = 0; i < clauses.size(); i++)
911 ca.reloc(clauses[i], to);
912}
913
914
916{
917 // Initialize the next region to a size corresponding to the estimated utilization degree. This
918 // is not precise but should avoid some unnecessary reallocations for the new region:
919 ClauseAllocator to(ca.size() - ca.wasted());
920
921 relocAll(to);
922 if (verbosity >= 2)
923 printf("| Garbage collection: %12d bytes => %12d bytes |\n",
925 to.moveTo(ca);
926}
927
unsigned int uint32_t
Definition Fxch.h:32
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define l_True
Definition bmcBmcS.c:35
#define l_Undef
Definition bmcBmcS.c:34
#define l_False
Definition bmcBmcS.c:36
#define var_Undef
Definition SolverTypes.h:45
#define INT32_MAX
Definition pstdint.h:415
ABC_NAMESPACE_IMPL_START typedef signed char value
void moveTo(ClauseAllocator &to)
float & activity()
uint32_t size() const
Definition Alloc.h:58
double learntsize_factor
Definition Solver.h:131
vec< Lit > conflict
Definition Solver.h:112
int64_t simpDB_props
Definition Solver.h:188
vec< double > activity
Definition Solver.h:176
Lit pickBranchLit()
Definition Solver.cpp:227
uint64_t tot_literals
Definition Solver.h:140
bool addClause_(vec< Lit > &ps)
Definition Solver.cpp:134
uint64_t clauses_literals
Definition Solver.h:140
CRef propagate()
Definition Solver.cpp:451
lbool search(int nof_conflicts)
Definition Solver.cpp:616
vec< Lit > analyze_stack
Definition Solver.h:200
void toDimacs(FILE *f, const vec< Lit > &assumps)
Definition Solver.cpp:833
uint64_t starts
Definition Solver.h:139
double learntsize_inc
Definition Solver.h:132
double random_seed
Definition Solver.h:121
int simpDB_assigns
Definition Solver.h:187
uint64_t propagations
Definition Solver.h:139
vec< lbool > assigns
Definition Solver.h:180
int nLearnts() const
Definition Solver.h:328
void checkGarbage()
Definition Solver.h:305
void cancelUntil(int level)
Definition Solver.cpp:209
void claDecayActivity()
Definition Solver.h:297
void varDecayActivity()
Definition Solver.h:284
bool litRedundant(Lit p, uint32_t abstract_levels)
Definition Solver.cpp:363
bool remove_satisfied
Definition Solver.h:192
void claBumpActivity(Clause &c)
Definition Solver.h:298
int nVars() const
Definition Solver.h:329
virtual void garbageCollect()
Definition Solver.cpp:915
double progressEstimate() const
Definition Solver.cpp:710
uint64_t rnd_decisions
Definition Solver.h:139
void relocAll(ClauseAllocator &to)
Definition Solver.cpp:878
int64_t propagation_budget
Definition Solver.h:211
vec< char > seen
Definition Solver.h:199
bool locked(const Clause &c) const
Definition Solver.h:317
void removeClause(CRef cr)
Definition Solver.cpp:190
int64_t conflict_budget
Definition Solver.h:210
double var_inc
Definition Solver.h:177
void reduceDB()
Definition Solver.cpp:527
void newDecisionLevel()
Definition Solver.h:318
bool rnd_init_act
Definition Solver.h:126
void detachClause(CRef cr, bool strict=false)
Definition Solver.cpp:173
double clause_decay
Definition Solver.h:119
CRef reason(Var x) const
Definition Solver.h:278
double restart_inc
Definition Solver.h:130
void rebuildOrderHeap()
Definition Solver.cpp:561
void analyze(CRef confl, vec< Lit > &out_learnt, int &out_btlevel)
Definition Solver.cpp:266
void attachClause(CRef cr)
Definition Solver.cpp:164
int level(Var x) const
Definition Solver.h:279
bool luby_restart
Definition Solver.h:122
void removeSatisfied(vec< CRef > &cs)
Definition Solver.cpp:547
static double drand(double &seed)
Definition Solver.h:263
void analyzeFinal(Lit p, vec< Lit > &out_conflict)
Definition Solver.cpp:401
uint64_t conflicts
Definition Solver.h:139
double var_decay
Definition Solver.h:118
double random_var_freq
Definition Solver.h:120
void insertVarOrder(Var x)
Definition Solver.h:281
uint64_t learnts_literals
Definition Solver.h:140
double max_learnts
Definition Solver.h:204
vec< int > trail_lim
Definition Solver.h:184
int learntsize_adjust_cnt
Definition Solver.h:206
bool withinBudget() const
Definition Solver.h:345
double cla_inc
Definition Solver.h:175
uint32_t abstractLevel(Var x) const
Definition Solver.h:321
vec< char > polarity
Definition Solver.h:181
vec< lbool > model
Definition Solver.h:111
OccLists< Lit, vec< Watcher >, WatcherDeleted > watches
Definition Solver.h:179
vec< Lit > trail
Definition Solver.h:183
ClauseAllocator ca
Definition Solver.h:194
static int irand(double &seed, int size)
Definition Solver.h:270
static VarData mkVarData(CRef cr, int l)
Definition Solver.h:147
virtual ~Solver()
Definition Solver.cpp:104
void varBumpActivity(Var v, double inc)
Definition Solver.h:286
uint64_t dec_vars
Definition Solver.h:140
vec< VarData > vardata
Definition Solver.h:185
vec< char > decision
Definition Solver.h:182
lbool solve_()
Definition Solver.cpp:753
uint64_t max_literals
Definition Solver.h:140
vec< Lit > analyze_toclear
Definition Solver.h:201
int decisionLevel() const
Definition Solver.h:320
Var newVar(bool polarity=true, bool dvar=true)
Definition Solver.cpp:116
int nAssigns() const
Definition Solver.h:326
double garbage_frac
Definition Solver.h:127
bool simplify()
Definition Solver.cpp:579
void setDecisionVar(Var v, bool b)
Definition Solver.h:332
vec< Lit > assumptions
Definition Solver.h:189
vec< CRef > learnts
Definition Solver.h:174
double learntsize_adjust_inc
Definition Solver.h:135
double learntsize_adjust_confl
Definition Solver.h:205
double progress_estimate
Definition Solver.h:191
vec< CRef > clauses
Definition Solver.h:173
uint64_t decisions
Definition Solver.h:139
int nClauses() const
Definition Solver.h:327
void uncheckedEnqueue(Lit p, CRef from=CRef_Undef)
Definition Solver.cpp:431
uint64_t solves
Definition Solver.h:139
int restart_first
Definition Solver.h:129
bool asynch_interrupt
Definition Solver.h:212
Heap< VarOrderLt > order_heap
Definition Solver.h:190
int learntsize_adjust_start_confl
Definition Solver.h:134
bool satisfied(const Clause &c) const
Definition Solver.cpp:200
void shrink(int nelems)
Definition Vec.h:66
void copyTo(vec< T > &copy) const
Definition Vec.h:92
int size(void) const
Definition Vec.h:65
void clear(bool dealloc=false)
Definition Vec.h:126
void push(void)
Definition Vec.h:75
void map()
Cube * p
Definition exorList.c:222
RegionAllocator< uint32_t >::Ref CRef
Definition Alg.h:28
const CRef CRef_Undef
void sort(T *array, int size, LessThan lt)
Definition Sort.h:58
int var(Lit p)
Definition SolverTypes.h:64
RegionAllocator< uint32_t >::Ref CRef
Lit mkLit(Var var, bool sign=false)
Definition SolverTypes.h:60
bool sign(Lit p)
Definition SolverTypes.h:63
const Lit lit_Undef
Definition SolverTypes.h:74
#define true
Definition place_base.h:28
#define false
Definition place_base.h:29
double luby(double y, int x)
Definition satSolver.c:1797
signed char lbool
Definition satVec.h:135
Definition file.h:23
reduceDB_lt(ClauseAllocator &ca_)
Definition Solver.cpp:523
ClauseAllocator & ca
Definition Solver.cpp:522
#define assert(ex)
Definition util_old.h:213
VOID_HACK exit()
#define HUGE_VAL
Definition util_old.h:295