yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SimpSolver.cc
Go to the documentation of this file.
1 #define __STDC_FORMAT_MACROS
2 #define __STDC_LIMIT_MACROS
3 /***********************************************************************************[SimpSolver.cc]
4 Copyright (c) 2006, Niklas Een, Niklas Sorensson
5 Copyright (c) 2007-2010, Niklas Sorensson
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
8 associated documentation files (the "Software"), to deal in the Software without restriction,
9 including without limitation the rights to use, copy, modify, merge, publish, distribute,
10 sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in all copies or
14 substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
17 NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
20 OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 **************************************************************************************************/
22 
23 #include "Sort.h"
24 #include "SimpSolver.h"
25 #include "System.h"
26 
27 using namespace Minisat;
28 
29 //=================================================================================================
30 // Options:
31 
32 
33 static const char* _cat = "SIMP";
34 
35 static BoolOption opt_use_asymm (_cat, "asymm", "Shrink clauses by asymmetric branching.", false);
36 static BoolOption opt_use_rcheck (_cat, "rcheck", "Check if a clause is already implied. (costly)", false);
37 static BoolOption opt_use_elim (_cat, "elim", "Perform variable elimination.", true);
38 static IntOption opt_grow (_cat, "grow", "Allow a variable elimination step to grow by a number of clauses.", 0);
39 static IntOption opt_clause_lim (_cat, "cl-lim", "Variables are not eliminated if it produces a resolvent with a length above this limit. -1 means no limit", 20, IntRange(-1, INT32_MAX));
40 static IntOption opt_subsumption_lim (_cat, "sub-lim", "Do not check if subsumption against a clause larger than this. -1 means no limit.", 1000, IntRange(-1, INT32_MAX));
41 static DoubleOption opt_simp_garbage_frac(_cat, "simp-gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered during simplification.", 0.5, DoubleRange(0, false, HUGE_VAL, false));
42 
43 
44 //=================================================================================================
45 // Constructor/Destructor:
46 
47 
49  grow (opt_grow)
50  , clause_lim (opt_clause_lim)
51  , subsumption_lim (opt_subsumption_lim)
52  , simp_garbage_frac (opt_simp_garbage_frac)
53  , use_asymm (opt_use_asymm)
54  , use_rcheck (opt_use_rcheck)
55  , use_elim (opt_use_elim)
56  , extend_model (true)
57  , merges (0)
58  , asymm_lits (0)
59  , eliminated_vars (0)
60  , elimorder (1)
61  , use_simplification (true)
62  , occurs (ClauseDeleted(ca))
63  , elim_heap (ElimLt(n_occ))
64  , bwdsub_assigns (0)
65  , n_touched (0)
66 {
67  vec<Lit> dummy(1,lit_Undef);
68  ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below.
69  bwdsub_tmpunit = ca.alloc(dummy);
70  remove_satisfied = false;
71 }
72 
73 
75 {
76 }
77 
78 
79 Var SimpSolver::newVar(lbool upol, bool dvar) {
80  Var v = Solver::newVar(upol, dvar);
81 
82  frozen .insert(v, (char)false);
83  eliminated.insert(v, (char)false);
84 
85  if (use_simplification){
86  n_occ .insert( mkLit(v), 0);
87  n_occ .insert(~mkLit(v), 0);
88  occurs .init (v);
89  touched .insert(v, 0);
90  elim_heap .insert(v);
91  }
92  return v; }
93 
94 
96 {
97  assert(!isEliminated(var(l)));
98  if (!use_simplification && var(l) >= max_simp_var)
99  // Note: Guarantees that no references to this variable is
100  // left in model extension datastructure. Could be improved!
102  else
103  // Otherwise, don't allow variable to be reused.
105 }
106 
107 
108 lbool SimpSolver::solve_(bool do_simp, bool turn_off_simp)
109 {
110  vec<Var> extra_frozen;
111  lbool result = l_True;
112 
113  do_simp &= use_simplification;
114 
115  if (do_simp){
116  // Assumptions must be temporarily frozen to run variable elimination:
117  for (int i = 0; i < assumptions.size(); i++){
118  Var v = var(assumptions[i]);
119 
120  // If an assumption has been eliminated, remember it.
121  assert(!isEliminated(v));
122 
123  if (!frozen[v]){
124  // Freeze and store.
125  setFrozen(v, true);
126  extra_frozen.push(v);
127  } }
128 
129  result = lbool(eliminate(turn_off_simp));
130  }
131 
132  if (result == l_True)
133  result = Solver::solve_();
134  else if (verbosity >= 1)
135  printf("===============================================================================\n");
136 
137  if (result == l_True && extend_model)
138  extendModel();
139 
140  if (do_simp)
141  // Unfreeze the assumptions that were frozen:
142  for (int i = 0; i < extra_frozen.size(); i++)
143  setFrozen(extra_frozen[i], false);
144 
145  return result;
146 }
147 
148 
149 
151 {
152 #ifndef NDEBUG
153  for (int i = 0; i < ps.size(); i++)
154  assert(!isEliminated(var(ps[i])));
155 #endif
156 
157  int nclauses = clauses.size();
158 
159  if (use_rcheck && implied(ps))
160  return true;
161 
162  if (!Solver::addClause_(ps))
163  return false;
164 
165  if (use_simplification && clauses.size() == nclauses + 1){
166  CRef cr = clauses.last();
167  const Clause& c = ca[cr];
168 
169  // NOTE: the clause is added to the queue immediately and then
170  // again during 'gatherTouchedClauses()'. If nothing happens
171  // in between, it will only be checked once. Otherwise, it may
172  // be checked twice unnecessarily. This is an unfortunate
173  // consequence of how backward subsumption is used to mimic
174  // forward subsumption.
176  for (int i = 0; i < c.size(); i++){
177  occurs[var(c[i])].push(cr);
178  n_occ[c[i]]++;
179  touched[var(c[i])] = 1;
180  n_touched++;
181  if (elim_heap.inHeap(var(c[i])))
182  elim_heap.increase(var(c[i]));
183  }
184  }
185 
186  return true;
187 }
188 
189 
191 {
192  const Clause& c = ca[cr];
193 
194  if (use_simplification)
195  for (int i = 0; i < c.size(); i++){
196  n_occ[c[i]]--;
197  updateElimHeap(var(c[i]));
198  occurs.smudge(var(c[i]));
199  }
200 
202 }
203 
204 
206 {
207  Clause& c = ca[cr];
208  assert(decisionLevel() == 0);
209  assert(use_simplification);
210 
211  // FIX: this is too inefficient but would be nice to have (properly implemented)
212  // if (!find(subsumption_queue, &c))
214 
215  if (c.size() == 2){
216  removeClause(cr);
217  c.strengthen(l);
218  }else{
219  detachClause(cr, true);
220  c.strengthen(l);
221  attachClause(cr);
222  remove(occurs[var(l)], cr);
223  n_occ[l]--;
224  updateElimHeap(var(l));
225  }
226 
227  return c.size() == 1 ? enqueue(c[0]) && propagate() == CRef_Undef : true;
228 }
229 
230 
231 // Returns FALSE if clause is always satisfied ('out_clause' should not be used).
232 bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
233 {
234  merges++;
235  out_clause.clear();
236 
237  bool ps_smallest = _ps.size() < _qs.size();
238  const Clause& ps = ps_smallest ? _qs : _ps;
239  const Clause& qs = ps_smallest ? _ps : _qs;
240 
241  for (int i = 0; i < qs.size(); i++){
242  if (var(qs[i]) != v){
243  for (int j = 0; j < ps.size(); j++)
244  if (var(ps[j]) == var(qs[i])){
245  if (ps[j] == ~qs[i])
246  return false;
247  else
248  goto next;
249  }
250  out_clause.push(qs[i]);
251  }
252  next:;
253  }
254 
255  for (int i = 0; i < ps.size(); i++)
256  if (var(ps[i]) != v)
257  out_clause.push(ps[i]);
258 
259  return true;
260 }
261 
262 
263 // Returns FALSE if clause is always satisfied.
264 bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, int& size)
265 {
266  merges++;
267 
268  bool ps_smallest = _ps.size() < _qs.size();
269  const Clause& ps = ps_smallest ? _qs : _ps;
270  const Clause& qs = ps_smallest ? _ps : _qs;
271  const Lit* __ps = (const Lit*)ps;
272  const Lit* __qs = (const Lit*)qs;
273 
274  size = ps.size()-1;
275 
276  for (int i = 0; i < qs.size(); i++){
277  if (var(__qs[i]) != v){
278  for (int j = 0; j < ps.size(); j++)
279  if (var(__ps[j]) == var(__qs[i])){
280  if (__ps[j] == ~__qs[i])
281  return false;
282  else
283  goto next;
284  }
285  size++;
286  }
287  next:;
288  }
289 
290  return true;
291 }
292 
293 
295 {
296  if (n_touched == 0) return;
297 
298  int i,j;
299  for (i = j = 0; i < subsumption_queue.size(); i++)
300  if (ca[subsumption_queue[i]].mark() == 0)
301  ca[subsumption_queue[i]].mark(2);
302 
303  for (i = 0; i < nVars(); i++)
304  if (touched[i]){
305  const vec<CRef>& cs = occurs.lookup(i);
306  for (j = 0; j < cs.size(); j++)
307  if (ca[cs[j]].mark() == 0){
308  subsumption_queue.insert(cs[j]);
309  ca[cs[j]].mark(2);
310  }
311  touched[i] = 0;
312  }
313 
314  for (i = 0; i < subsumption_queue.size(); i++)
315  if (ca[subsumption_queue[i]].mark() == 2)
316  ca[subsumption_queue[i]].mark(0);
317 
318  n_touched = 0;
319 }
320 
321 
323 {
324  assert(decisionLevel() == 0);
325 
327  for (int i = 0; i < c.size(); i++)
328  if (value(c[i]) == l_True){
329  cancelUntil(0);
330  return true;
331  }else if (value(c[i]) != l_False){
332  assert(value(c[i]) == l_Undef);
333  uncheckedEnqueue(~c[i]);
334  }
335 
336  bool result = propagate() != CRef_Undef;
337  cancelUntil(0);
338  return result;
339 }
340 
341 
342 // Backward subsumption + backward subsumption resolution
344 {
345  int cnt = 0;
346  int subsumed = 0;
347  int deleted_literals = 0;
348  assert(decisionLevel() == 0);
349 
350  while (subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()){
351 
352  // Empty subsumption queue and return immediately on user-interrupt:
353  if (asynch_interrupt){
356  break; }
357 
358  // Check top-level assignments by creating a dummy clause and placing it in the queue:
359  if (subsumption_queue.size() == 0 && bwdsub_assigns < trail.size()){
360  Lit l = trail[bwdsub_assigns++];
361  ca[bwdsub_tmpunit][0] = l;
362  ca[bwdsub_tmpunit].calcAbstraction();
364 
366  Clause& c = ca[cr];
367 
368  if (c.mark()) continue;
369 
370  if (verbose && verbosity >= 2 && cnt++ % 1000 == 0)
371  printf("subsumption left: %10d (%10d subsumed, %10d deleted literals)\r", subsumption_queue.size(), subsumed, deleted_literals);
372 
373  assert(c.size() > 1 || value(c[0]) == l_True); // Unit-clauses should have been propagated before this point.
374 
375  // Find best variable to scan:
376  Var best = var(c[0]);
377  for (int i = 1; i < c.size(); i++)
378  if (occurs[var(c[i])].size() < occurs[best].size())
379  best = var(c[i]);
380 
381  // Search all candidates:
382  vec<CRef>& _cs = occurs.lookup(best);
383  CRef* cs = (CRef*)_cs;
384 
385  for (int j = 0; j < _cs.size(); j++)
386  if (c.mark())
387  break;
388  else if (!ca[cs[j]].mark() && cs[j] != cr && (subsumption_lim == -1 || ca[cs[j]].size() < subsumption_lim)){
389  Lit l = c.subsumes(ca[cs[j]]);
390 
391  if (l == lit_Undef)
392  subsumed++, removeClause(cs[j]);
393  else if (l != lit_Error){
394  deleted_literals++;
395 
396  if (!strengthenClause(cs[j], ~l))
397  return false;
398 
399  // Did current candidate get deleted from cs? Then check candidate at index j again:
400  if (var(l) == best)
401  j--;
402  }
403  }
404  }
405 
406  return true;
407 }
408 
409 
411 {
412  Clause& c = ca[cr];
413  assert(decisionLevel() == 0);
414 
415  if (c.mark() || satisfied(c)) return true;
416 
418  Lit l = lit_Undef;
419  for (int i = 0; i < c.size(); i++)
420  if (var(c[i]) != v && value(c[i]) != l_False)
421  uncheckedEnqueue(~c[i]);
422  else
423  l = c[i];
424 
425  if (propagate() != CRef_Undef){
426  cancelUntil(0);
427  asymm_lits++;
428  if (!strengthenClause(cr, l))
429  return false;
430  }else
431  cancelUntil(0);
432 
433  return true;
434 }
435 
436 
438 {
439  assert(use_simplification);
440 
441  const vec<CRef>& cls = occurs.lookup(v);
442 
443  if (value(v) != l_Undef || cls.size() == 0)
444  return true;
445 
446  for (int i = 0; i < cls.size(); i++)
447  if (!asymm(v, cls[i]))
448  return false;
449 
450  return backwardSubsumptionCheck();
451 }
452 
453 
454 static void mkElimClause(vec<uint32_t>& elimclauses, Lit x)
455 {
456  elimclauses.push(toInt(x));
457  elimclauses.push(1);
458 }
459 
460 
461 static void mkElimClause(vec<uint32_t>& elimclauses, Var v, Clause& c)
462 {
463  int first = elimclauses.size();
464  int v_pos = -1;
465 
466  // Copy clause to elimclauses-vector. Remember position where the
467  // variable 'v' occurs:
468  for (int i = 0; i < c.size(); i++){
469  elimclauses.push(toInt(c[i]));
470  if (var(c[i]) == v)
471  v_pos = i + first;
472  }
473  assert(v_pos != -1);
474 
475  // Swap the first literal with the 'v' literal, so that the literal
476  // containing 'v' will occur first in the clause:
477  uint32_t tmp = elimclauses[v_pos];
478  elimclauses[v_pos] = elimclauses[first];
479  elimclauses[first] = tmp;
480 
481  // Store the length of the clause last:
482  elimclauses.push(c.size());
483 }
484 
485 
486 
488 {
489  assert(!frozen[v]);
490  assert(!isEliminated(v));
491  assert(value(v) == l_Undef);
492 
493  // Split the occurrences into positive and negative:
494  //
495  const vec<CRef>& cls = occurs.lookup(v);
496  vec<CRef> pos, neg;
497  for (int i = 0; i < cls.size(); i++)
498  (find(ca[cls[i]], mkLit(v)) ? pos : neg).push(cls[i]);
499 
500  // Check wether the increase in number of clauses stays within the allowed ('grow'). Moreover, no
501  // clause must exceed the limit on the maximal clause size (if it is set):
502  //
503  int cnt = 0;
504  int clause_size = 0;
505 
506  for (int i = 0; i < pos.size(); i++)
507  for (int j = 0; j < neg.size(); j++)
508  if (merge(ca[pos[i]], ca[neg[j]], v, clause_size) &&
509  (++cnt > cls.size() + grow || (clause_lim != -1 && clause_size > clause_lim)))
510  return true;
511 
512  // Delete and store old clauses:
513  eliminated[v] = true;
514  setDecisionVar(v, false);
515  eliminated_vars++;
516 
517  if (pos.size() > neg.size()){
518  for (int i = 0; i < neg.size(); i++)
519  mkElimClause(elimclauses, v, ca[neg[i]]);
521  }else{
522  for (int i = 0; i < pos.size(); i++)
523  mkElimClause(elimclauses, v, ca[pos[i]]);
525  }
526 
527  for (int i = 0; i < cls.size(); i++)
528  removeClause(cls[i]);
529 
530  // Produce clauses in cross product:
531  vec<Lit>& resolvent = add_tmp;
532  for (int i = 0; i < pos.size(); i++)
533  for (int j = 0; j < neg.size(); j++)
534  if (merge(ca[pos[i]], ca[neg[j]], v, resolvent) && !addClause_(resolvent))
535  return false;
536 
537  // Free occurs list for this variable:
538  occurs[v].clear(true);
539 
540  // Free watchers lists for this variable, if possible:
541  if (watches[ mkLit(v)].size() == 0) watches[ mkLit(v)].clear(true);
542  if (watches[~mkLit(v)].size() == 0) watches[~mkLit(v)].clear(true);
543 
544  return backwardSubsumptionCheck();
545 }
546 
547 
549 {
550  assert(!frozen[v]);
551  assert(!isEliminated(v));
552  assert(value(v) == l_Undef);
553 
554  if (!ok) return false;
555 
556  eliminated[v] = true;
557  setDecisionVar(v, false);
558  const vec<CRef>& cls = occurs.lookup(v);
559 
560  vec<Lit>& subst_clause = add_tmp;
561  for (int i = 0; i < cls.size(); i++){
562  Clause& c = ca[cls[i]];
563 
564  subst_clause.clear();
565  for (int j = 0; j < c.size(); j++){
566  Lit p = c[j];
567  subst_clause.push(var(p) == v ? x ^ sign(p) : p);
568  }
569 
570  removeClause(cls[i]);
571 
572  if (!addClause_(subst_clause))
573  return ok = false;
574  }
575 
576  return true;
577 }
578 
579 
581 {
582  int i, j;
583  Lit x;
584 
585  for (i = elimclauses.size()-1; i > 0; i -= j){
586  for (j = elimclauses[i--]; j > 1; j--, i--)
587  if (modelValue(toLit(elimclauses[i])) != l_False)
588  goto next;
589 
590  x = toLit(elimclauses[i]);
591  model[var(x)] = lbool(!sign(x));
592  next:;
593  }
594 }
595 
596 
597 bool SimpSolver::eliminate(bool turn_off_elim)
598 {
599  if (!simplify())
600  return false;
601  else if (!use_simplification)
602  return true;
603 
604  // Main simplification loop:
605  //
606  while (n_touched > 0 || bwdsub_assigns < trail.size() || elim_heap.size() > 0){
607 
609  // printf(" ## (time = %6.2f s) BWD-SUB: queue = %d, trail = %d\n", cpuTime(), subsumption_queue.size(), trail.size() - bwdsub_assigns);
610  if ((subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()) &&
611  !backwardSubsumptionCheck(true)){
612  ok = false; goto cleanup; }
613 
614  // Empty elim_heap and return immediately on user-interrupt:
615  if (asynch_interrupt){
616  assert(bwdsub_assigns == trail.size());
617  assert(subsumption_queue.size() == 0);
618  assert(n_touched == 0);
619  elim_heap.clear();
620  goto cleanup; }
621 
622  // printf(" ## (time = %6.2f s) ELIM: vars = %d\n", cpuTime(), elim_heap.size());
623  for (int cnt = 0; !elim_heap.empty(); cnt++){
624  Var elim = elim_heap.removeMin();
625 
626  if (asynch_interrupt) break;
627 
628  if (isEliminated(elim) || value(elim) != l_Undef) continue;
629 
630  if (verbosity >= 2 && cnt % 100 == 0)
631  printf("elimination left: %10d\r", elim_heap.size());
632 
633  if (use_asymm){
634  // Temporarily freeze variable. Otherwise, it would immediately end up on the queue again:
635  bool was_frozen = frozen[elim];
636  frozen[elim] = true;
637  if (!asymmVar(elim)){
638  ok = false; goto cleanup; }
639  frozen[elim] = was_frozen; }
640 
641  // At this point, the variable may have been set by assymetric branching, so check it
642  // again. Also, don't eliminate frozen variables:
643  if (use_elim && value(elim) == l_Undef && !frozen[elim] && !eliminateVar(elim)){
644  ok = false; goto cleanup; }
645 
647  }
648 
649  assert(subsumption_queue.size() == 0);
650  }
651  cleanup:
652 
653  // If no more simplification is needed, free all simplification-related data structures:
654  if (turn_off_elim){
655  touched .clear(true);
656  occurs .clear(true);
657  n_occ .clear(true);
658  elim_heap.clear(true);
659  subsumption_queue.clear(true);
660 
661  use_simplification = false;
662  remove_satisfied = true;
663  ca.extra_clause_field = false;
664  max_simp_var = nVars();
665 
666  // Force full cleanup (this is safe and desirable since it only happens once):
668  garbageCollect();
669  }else{
670  // Cheaper cleanup:
671  checkGarbage();
672  }
673 
674  if (verbosity >= 1 && elimclauses.size() > 0)
675  printf("| Eliminated clauses: %10.2f Mb |\n",
676  double(elimclauses.size() * sizeof(uint32_t)) / (1024*1024));
677 
678  return ok;
679 }
680 
681 
682 //=================================================================================================
683 // Garbage Collection methods:
684 
685 
687 {
688  if (!use_simplification) return;
689 
690  // All occurs lists:
691  //
692  for (int i = 0; i < nVars(); i++){
693  occurs.clean(i);
694  vec<CRef>& cs = occurs[i];
695  for (int j = 0; j < cs.size(); j++)
696  ca.reloc(cs[j], to);
697  }
698 
699  // Subsumption queue:
700  //
701  for (int i = subsumption_queue.size(); i > 0; i--){
703  if (ca[cr].mark()) continue;
704  ca.reloc(cr, to);
706  }
707 
708  // Temporary clause:
709  //
710  ca.reloc(bwdsub_tmpunit, to);
711 }
712 
713 
715 {
716  // Initialize the next region to a size corresponding to the estimated utilization degree. This
717  // is not precise but should avoid some unnecessary reallocations for the new region:
718  ClauseAllocator to(ca.size() - ca.wasted());
719 
720  to.extra_clause_field = ca.extra_clause_field; // NOTE: this is important to keep (or lose) the extra fields.
721  relocAll(to);
722  Solver::relocAll(to);
723  if (verbosity >= 2)
724  printf("| Garbage collection: %12d bytes => %12d bytes |\n",
726  to.moveTo(ca);
727 }
RegionAllocator< uint32_t >::Ref CRef
Definition: SolverTypes.h:137
#define INT32_MAX
Definition: ilang_lexer.cc:94
void removeClause(CRef cr)
Definition: SimpSolver.cc:190
const lbool l_False((uint8_t) 1)
ClauseAllocator ca
Definition: Solver.h:216
void releaseVar(Lit l)
Definition: SimpSolver.cc:95
void insert(K key, V val, V pad)
Definition: IntMap.h:49
static DoubleOption opt_simp_garbage_frac(_cat,"simp-gc-frac","The fraction of wasted memory allowed before a garbage collection is triggered during simplification.", 0.5, DoubleRange(0, false, HUGE_VAL, false))
void gatherTouchedClauses()
Definition: SimpSolver.cc:294
bool simplify()
Definition: Solver.cc:643
LMap< int > n_occ
Definition: SimpSolver.h:141
void relocAll(ClauseAllocator &to)
Definition: Solver.cc:1010
OccLists< Var, vec< CRef >, ClauseDeleted > occurs
Definition: SimpSolver.h:140
Lit mkLit(Var var, bool sign=false)
Definition: SolverTypes.h:63
lbool modelValue(Var x) const
Definition: Solver.h:352
int var(Lit p)
Definition: SolverTypes.h:67
void setFrozen(Var v, bool b)
Definition: SimpSolver.h:192
void clear(bool dispose=false)
Definition: IntMap.h:52
void strengthen(Lit p)
Definition: SolverTypes.h:469
uint32_t size() const
Definition: SolverTypes.h:263
Queue< CRef > subsumption_queue
Definition: SimpSolver.h:143
int size() const
Definition: Queue.h:42
vec< uint32_t > elimclauses
Definition: SimpSolver.h:137
bool addClause(const vec< Lit > &ps)
Definition: Solver.h:337
bool sign(Lit p)
Definition: SolverTypes.h:66
static IntOption opt_clause_lim(_cat,"cl-lim","Variables are not eliminated if it produces a resolvent with a length above this limit. -1 means no limit", 20, IntRange(-1, INT32_MAX))
void releaseVar(Lit l)
Definition: Solver.cc:147
void clear(bool dealloc=false)
Definition: Queue.h:41
const lbool l_Undef((uint8_t) 2)
void attachClause(CRef cr)
Definition: Solver.cc:186
void pop()
Definition: Queue.h:48
const T & last(void) const
Definition: Vec.h:84
void setDecisionVar(Var v, bool b)
Definition: Solver.h:361
void cancelUntil(int level)
Definition: Solver.cc:233
void insert(T elem)
Definition: Queue.h:49
Var newVar(lbool upol=l_Undef, bool dvar=true)
Definition: SimpSolver.cc:79
void updateElimHeap(Var v)
Definition: SimpSolver.h:179
void detachClause(CRef cr, bool strict=false)
Definition: Solver.cc:196
vec< int > trail_lim
Definition: Solver.h:193
virtual void garbageCollect()
Definition: SimpSolver.cc:714
int nVars() const
Definition: Solver.h:357
static BoolOption opt_use_asymm(_cat,"asymm","Shrink clauses by asymmetric branching.", false)
bool merge(const Clause &_ps, const Clause &_qs, Var v, vec< Lit > &out_clause)
Definition: SimpSolver.cc:232
VMap< char > eliminated
Definition: SimpSolver.h:146
bool eliminateVar(Var v)
Definition: SimpSolver.cc:487
const CRef CRef_Undef
Definition: SolverTypes.h:225
bool asymm(Var v, CRef cr)
Definition: SimpSolver.cc:410
int decisionLevel() const
Definition: Solver.h:348
bool asynch_interrupt
Definition: Solver.h:237
bool implied(const vec< Lit > &c)
Definition: SimpSolver.cc:322
vec< Lit > assumptions
Definition: Solver.h:194
void checkGarbage()
Definition: Solver.h:330
vec< CRef > clauses
Definition: Solver.h:190
void rebuildOrderHeap()
Definition: Solver.cc:625
void push(void)
Definition: Vec.h:74
Heap< Var, ElimLt > elim_heap
Definition: SimpSolver.h:142
bool addClause_(vec< Lit > &ps)
Definition: Solver.cc:156
Size size(void) const
Definition: Vec.h:64
bool strengthenClause(CRef cr, Lit l)
Definition: SimpSolver.cc:205
bool asymmVar(Var v)
Definition: SimpSolver.cc:437
void reloc(CRef &cr, ClauseAllocator &to)
Definition: SolverTypes.h:279
bool eliminate(bool turn_off_elim=false)
Definition: SimpSolver.cc:597
T peek() const
Definition: Queue.h:47
VMap< char > frozen
Definition: SimpSolver.h:144
void removeClause(CRef cr)
Definition: Solver.cc:214
void relocAll(ClauseAllocator &to)
Definition: SimpSolver.cc:686
vec< lbool > model
Definition: Solver.h:122
bool backwardSubsumptionCheck(bool verbose=false)
Definition: SimpSolver.cc:343
Var newVar(lbool upol=l_Undef, bool dvar=true)
Definition: Solver.cc:121
bool isEliminated(Var v) const
Definition: SimpSolver.h:178
const lbool l_True((uint8_t) 0)
static BoolOption opt_use_elim(_cat,"elim","Perform variable elimination.", true)
static const char * _cat
Definition: SimpSolver.cc:33
static void mkElimClause(vec< uint32_t > &elimclauses, Lit x)
Definition: SimpSolver.cc:454
lbool value(Var x) const
Definition: Solver.h:350
lbool solve_()
Definition: Solver.cc:841
void clear(bool dealloc=false)
Definition: Vec.h:125
CRef alloc(const vec< Lit > &ps, bool learnt=false)
Definition: SolverTypes.h:245
bool addClause_(vec< Lit > &ps)
Definition: SimpSolver.cc:150
int Var
Definition: SolverTypes.h:43
vec< Lit > add_tmp
Definition: Solver.h:227
uint32_t wasted() const
Definition: SolverTypes.h:264
bool enqueue(Lit p, CRef from=CRef_Undef)
Definition: Solver.h:336
const Lit lit_Error
Definition: SolverTypes.h:78
Lit subsumes(const Clause &other) const
Definition: SolverTypes.h:438
static bool find(V &ts, const T &t)
Definition: Alg.h:47
void uncheckedEnqueue(Lit p, CRef from=CRef_Undef)
Definition: Solver.cc:488
const Lit lit_Undef
Definition: SolverTypes.h:77
vec< Lit > trail
Definition: Solver.h:192
static BoolOption opt_use_rcheck(_cat,"rcheck","Check if a clause is already implied. (costly)", false)
bool substitute(Var v, Lit x)
Definition: SimpSolver.cc:548
bool satisfied(const Clause &c) const
Definition: Solver.cc:224
Lit toLit(int i)
Definition: SolverTypes.h:72
double simp_garbage_frac
Definition: SimpSolver.h:94
CRef propagate()
Definition: Solver.cc:508
int toInt(Var v)
Definition: SolverTypes.h:70
OccLists< Lit, vec< Watcher >, WatcherDeleted, MkIndexLit > watches
Definition: Solver.h:203
static IntOption opt_grow(_cat,"grow","Allow a variable elimination step to grow by a number of clauses.", 0)
static IntOption opt_subsumption_lim(_cat,"sub-lim","Do not check if subsumption against a clause larger than this. -1 means no limit.", 1000, IntRange(-1, INT32_MAX))
VMap< char > touched
Definition: SimpSolver.h:138
bool remove_satisfied
Definition: Solver.h:214