ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
cadical_decompose.cpp
Go to the documentation of this file.
1#include "global.h"
2
3#include "internal.hpp"
4
6
7namespace CaDiCaL {
8
10 if (!lrat)
11 return;
12 LOG ("binary chain starting at %d", from);
13 DFS &from_dfs = dfs[vlit (from)];
14 Clause *reason = from_dfs.parent;
15 if (!reason)
16 return;
17 CADICAL_assert (reason->size == 2);
18 mini_chain.push_back (reason->id);
19 int other = reason->literals[0];
20 other = other == from ? -reason->literals[1] : -other;
21 Flags &f = flags (other);
22 if (f.seen)
23 return;
24 f.seen = true;
25 analyzed.push_back (other);
27}
28
30 int from) {
31 vector<Clause *> result;
32 LOG ("binary chain starting at %d", from);
33 DFS &from_dfs = dfs[vlit (from)];
34 Clause *reason = from_dfs.parent;
35 while (reason) {
36 result.push_back (reason);
37 CADICAL_assert (reason->size == 2);
38 int other = reason->literals[0];
39 other = other == from ? -reason->literals[1] : -other;
40 Flags &f = flags (other);
41 if (f.seen)
42 break;
43 f.seen = true;
44 analyzed.push_back (other);
45 from = other;
46 DFS &from_dfs = dfs[vlit (from)];
47 reason = from_dfs.parent;
48 }
49 return result;
50}
51
53 if (!lrat)
54 return;
55 CADICAL_assert (lrat_chain.empty ());
56 CADICAL_assert (mini_chain.empty ());
57 for (auto &lit : scc) {
58 Flags &f = flags (lit);
59 if (f.seen)
60 return;
61 f.seen = true;
62 analyzed.push_back (lit);
64 for (auto p = mini_chain.rbegin (); p != mini_chain.rend (); p++) {
65 lrat_chain.push_back (*p);
66 }
67 mini_chain.clear ();
68 }
70}
71
73 const vector<vector<Clause *>> &dfs_chains, bool invert) {
75 LOG ("building chain for not subsumed clause");
76 CADICAL_assert (lrat_chain.empty ());
77 CADICAL_assert (sign_marked.empty ());
78 // build chain for each replaced literal
79 for (const auto lit : clause) {
80 auto other = lit;
81 if (val (other) > 0) {
82 if (marked_decomposed (other))
83 continue;
84 mark_decomposed (other);
85 int64_t id = unit_id (other);
86 lrat_chain.push_back (id);
87 continue;
88 }
89 CADICAL_assert (mini_chain.empty ());
90 for (auto p : dfs_chains[vlit (other)]) {
91 if (marked_decomposed (other))
92 continue;
93 mark_decomposed (other);
94 int implied = p->literals[0];
95 implied = implied == other ? -p->literals[1] : -implied;
96 LOG ("ADDED %d -> %d (%" PRId64 ")", implied, other, p->id);
97 other = implied;
98 mini_chain.push_back (p->id);
99 if (val (implied) <= 0)
100 continue;
102 break;
104 int64_t id = unit_id (implied);
105 mini_chain.push_back (id);
106 break;
107 }
108 if (invert)
109 for (auto p = mini_chain.rbegin (); p != mini_chain.rend (); p++)
110 lrat_chain.push_back (*p);
111 else
112 for (auto p = mini_chain.begin (); p != mini_chain.end (); p++)
113 lrat_chain.push_back (*p);
114 mini_chain.clear ();
115 }
117 LOG (lrat_chain, "lrat_chain:");
118}
119
121 LOG ("clearing %zd marked literals", sign_marked.size ());
122 for (const auto &lit : sign_marked) {
123 // CADICAL_assert (marked_signed (lit)); violated on purpose in factor
125 }
126 sign_marked.clear ();
127}
128
129// This performs one round of Tarjan's algorithm, e.g., equivalent literal
130// detection and substitution, on the whole formula. We might want to
131// repeat it since its application might produce new binary clauses or
132// units. Such units might even result in an empty clause.
133
135
136 if (!opts.decompose)
137 return false;
138 if (unsat)
139 return false;
141 return false;
142
144
146
147 stats.decompositions++;
148
149 const size_t size_dfs = 2 * (1 + (size_t) max_var);
150 DFS *dfs = new DFS[size_dfs];
151 DeferDeleteArray<DFS> dfs_delete (dfs);
152 int *reprs = new int[size_dfs];
153 DeferDeleteArray<int> reprs_delete (reprs);
154 clear_n (reprs, size_dfs);
155 vector<vector<Clause *>> dfs_chains;
156 dfs_chains.resize (size_dfs);
157 if (lrat) {
158 for (size_t i = 0; i > size_dfs; i++) {
159 vector<Clause *> empty;
160 dfs_chains[i] = empty;
161 }
162 }
163
164 int substituted = 0;
165#ifndef CADICAL_QUIET
166 int non_trivial_sccs = 0;
167 int before = active ();
168#endif
169 unsigned dfs_idx = 0;
170
171 vector<int> work; // depth first search working stack
172 vector<int> scc; // collects members of one SCC
173
174 // The binary implication graph might have disconnected components and
175 // thus we have in general to start several depth first searches.
176
177 for (auto root_idx : vars) {
178 if (unsat)
179 break;
180 if (!active (root_idx))
181 continue;
182 for (int root_sign = -1; !unsat && root_sign <= 1; root_sign += 2) {
183 int root = root_sign * root_idx;
184 if (dfs[vlit (root)].min == TRAVERSED)
185 continue; // skip traversed
186 LOG ("new dfs search starting at root %d", root);
187 CADICAL_assert (work.empty ());
188 CADICAL_assert (scc.empty ());
189 work.push_back (root);
190 while (!unsat && !work.empty ()) {
191 int parent = work.back ();
192 DFS &parent_dfs = dfs[vlit (parent)];
193 if (parent_dfs.min == TRAVERSED) { // skip traversed
194 CADICAL_assert (reprs[vlit (parent)]);
195 work.pop_back ();
196 } else {
197 CADICAL_assert (!reprs[vlit (parent)]);
198
199 // Go over all implied literals, thus need to iterate over all
200 // binary watched clauses with the negation of 'parent'.
201
202 Watches &ws = watches (-parent);
203
204 // Two cases: Either the node has never been visited before, i.e.,
205 // it's depth first search index is zero, then perform the
206 // 'pre-fix' work before visiting it's children. Otherwise all
207 // it's children and nodes reachable from those children have been
208 // visited and their minimum reachable depth first search index
209 // has been computed. This second case is the 'post-fix' work.
210
211 if (parent_dfs.idx) { // post-fix
212
213 work.pop_back (); // 'parent' done
214
215 // Get the minimum reachable depth first search index reachable
216 // from the children of 'parent'.
217
218 unsigned new_min = parent_dfs.min;
219
220 for (const auto &w : ws) {
221 if (!w.binary ())
222 continue;
223 const int child = w.blit;
224 if (!active (child))
225 continue;
226 DFS &child_dfs = dfs[vlit (child)];
227 if (new_min > child_dfs.min)
228 new_min = child_dfs.min;
229 }
230
231 LOG ("post-fix work dfs search %d index %u reaches minimum %u",
232 parent, parent_dfs.idx, new_min);
233
234 if (parent_dfs.idx == new_min) { // entry to SCC
235
236 // All nodes on the 'scc' stack after and including 'parent'
237 // are in the same SCC. Their representative is computed as
238 // the smallest literal (index-wise) in the SCC. If the SCC
239 // contains both a literal and its negation, then the formula
240 // becomes unsatisfiable.
241
242 if (lrat) {
243 CADICAL_assert (analyzed.empty ());
244 int other, first = 0;
245 bool conflicting = false;
246 size_t j = scc.size ();
247 do {
248 CADICAL_assert (j > 0);
249 other = scc[--j];
250 if (!first || vlit (other) < vlit (first))
251 first = other;
252 Flags &f = flags (other);
253 if (other == -parent) {
254 conflicting = true; // conflicting scc
255 }
256 if (f.seen) {
257 continue; // also conflicting scc
258 }
259 f.seen = true;
260 analyzed.push_back (other);
261 } while (other != parent);
262
263 CADICAL_assert (!conflicting || first > 0);
264 vector<int> to_justify;
265 if (conflicting) {
266 LOG ("conflicting scc simulating up at %d", parent);
267 to_justify.push_back (-parent);
268 } else
269 to_justify.push_back (first);
270 while (!to_justify.empty ()) {
271 const int next = to_justify.back ();
272 to_justify.pop_back ();
273 Watches &next_ws = watches (-next);
274 for (const auto &w : next_ws) {
275 if (!w.binary ())
276 continue;
277 const int child = w.blit;
278 if (!active (child))
279 continue;
280 if (!flags (child).seen)
281 continue;
282 DFS &child_dfs = dfs[vlit (child)];
283 if (child_dfs.parent)
284 continue;
285 child_dfs.parent = w.clause;
286 to_justify.push_back (child);
287 }
288 }
289
291 }
292
293 int other, repr = parent;
294#ifndef CADICAL_QUIET
295 int size = 0;
296#endif
297 CADICAL_assert (!scc.empty ());
298 size_t j = scc.size ();
299 do {
300 CADICAL_assert (j > 0);
301 other = scc[--j];
302 if (other == -parent) {
303 LOG ("both %d and %d in one SCC", parent, -parent);
304 if (lrat) {
305 Flags &f = flags (-parent);
306 f.seen = true;
307 analyzed.push_back (-parent);
308 decompose_analyze_binary_chain (dfs, parent);
309 for (auto p : mini_chain)
310 lrat_chain.push_back (p);
311 mini_chain.clear ();
312 }
313 assign_unit (parent);
314#ifndef CADICAL_NDEBUG
315 bool ok =
316#endif
317 propagate ();
318 CADICAL_assert (!ok);
320 lrat_chain.clear ();
321 } else {
322 if (abs (other) < abs (repr))
323 repr = other;
324#ifndef CADICAL_QUIET
325 size++;
326#endif
327 }
328 } while (!unsat && other != parent);
329
330 if (unsat)
331 break;
332#ifndef CADICAL_QUIET
333 LOG ("SCC of representative %d of size %d", repr, size);
334#endif
335 do {
336 CADICAL_assert (!scc.empty ());
337 other = scc.back ();
338 scc.pop_back ();
339 dfs[vlit (other)].min = TRAVERSED;
340 if (frozen (other)) {
341 reprs[vlit (other)] = other;
342 continue;
343 }
344 reprs[vlit (other)] = repr;
345 if (other == repr)
346 continue;
347 substituted++;
348 LOG ("literal %d in SCC of %d", other, repr);
349 if (!lrat)
350 continue;
351 CADICAL_assert (mini_chain.empty ());
352 Flags &f = flags (repr);
353 f.seen = true;
354 analyzed.push_back (repr);
355 // no need to reverse dfs_chain because this is handled by
356 // build_lrat_for_clause.
357 dfs_chains[vlit (other)] =
360 } while (other != parent);
361
362#ifndef CADICAL_QUIET
363 if (size > 1)
364 non_trivial_sccs++;
365#endif
366
367 } else {
368
369 // Current node 'parent' is in a non-trivial SCC but is not
370 // the entry point of the SCC in this depth first search, so
371 // keep it on the SCC stack until the entry point is reached.
372
373 parent_dfs.min = new_min;
374 }
375
376 } else { // pre-fix
377
378 dfs_idx++;
379 CADICAL_assert (dfs_idx < TRAVERSED);
380 parent_dfs.idx = parent_dfs.min = dfs_idx;
381 scc.push_back (parent);
382
383 LOG ("pre-fix work dfs search %d index %u", parent, dfs_idx);
384
385 // Now traverse all the children in the binary implication
386 // graph but keep 'parent' on the stack for 'post-fix' work.
387
388 for (const auto &w : ws) {
389 if (!w.binary ())
390 continue;
391 const int child = w.blit;
392 if (!active (child))
393 continue;
394 DFS &child_dfs = dfs[vlit (child)];
395 if (child_dfs.idx)
396 continue;
397 work.push_back (child);
398 }
399 }
400 }
401 }
402 }
403 }
404
405 erase_vector (work);
406 erase_vector (scc);
407 // delete [] dfs; need to postpone until after changing clauses...
408
409 // Only keep the representatives 'repr' mapping.
410
411 PHASE ("decompose", stats.decompositions,
412 "%d non-trivial sccs, %d substituted %.2f%%", non_trivial_sccs,
413 substituted, percent (substituted, before));
414
415 bool new_unit = false, new_binary_clause = false;
416
417 // Finally, mark substituted literals as such and push the equivalences of
418 // the substituted literals to their representative on the extension
419 // stack to fix an assignment during 'extend'.
420 // It is also necessary to do so for proper IDRUP/LIDRUP/Resolution proofs
421
422 vector<int64_t> decompose_ids;
423 const size_t size = 2 * (1 + (size_t) max_var);
424 decompose_ids.resize (size);
425
426 for (auto idx : vars) {
427 if (!substituted)
428 break;
429 if (unsat)
430 break;
431 if (!active (idx))
432 continue;
433 int other = reprs[vlit (idx)];
434 if (other == idx)
435 continue;
436 CADICAL_assert (!flags (other).eliminated ());
437 CADICAL_assert (!flags (other).substituted ());
438
439 LOG ("marking equivalence of %d and %d", idx, other);
440 CADICAL_assert (clause.empty ());
441 CADICAL_assert (lrat_chain.empty ());
442 clause.push_back (other);
443 clause.push_back (-idx);
444 if (lrat) {
445 build_lrat_for_clause (dfs_chains);
446 CADICAL_assert (!lrat_chain.empty ());
447 }
448
449 const int64_t id1 = ++clause_id;
450 if (proof) {
451 proof->add_derived_clause (id1, false, clause, lrat_chain);
452 proof->weaken_minus (id1, clause);
453 }
454 external->push_binary_clause_on_extension_stack (id1, -idx, other);
455
456 decompose_ids[vlit (-idx)] = id1;
457
458 lrat_chain.clear ();
459 clause.clear ();
460
461 CADICAL_assert (clause.empty ());
462 CADICAL_assert (lrat_chain.empty ());
463 clause.push_back (idx);
464 clause.push_back (-other);
465 if (lrat) {
466 build_lrat_for_clause (dfs_chains);
467 CADICAL_assert (!lrat_chain.empty ());
468 }
469 const int64_t id2 = ++clause_id;
470 if (proof) {
471 proof->add_derived_clause (id2, false, clause, lrat_chain);
472 proof->weaken_minus (id2, clause);
473 }
474 external->push_binary_clause_on_extension_stack (id2, idx, -other);
475 decompose_ids[vlit (idx)] = id2;
476
477 clause.clear ();
478 lrat_chain.clear ();
479 }
480
481 vector<Clause *> postponed_garbage;
482
483 // Now go over all clauses and find clause which contain literals that
484 // should be substituted by their representative.
485
486 size_t clauses_size = clauses.size ();
487#ifndef CADICAL_QUIET
488 size_t garbage = 0, replaced = 0;
489#endif
490 for (size_t i = 0; substituted && !unsat && i < clauses_size; i++) {
491 Clause *c = clauses[i];
492 if (c->garbage)
493 continue;
494 int j, size = c->size;
495 for (j = 0; j < size; j++) {
496 const int lit = c->literals[j];
497 if (reprs[vlit (lit)] != lit)
498 break;
499 }
500
501 if (j == size)
502 continue;
503
504#ifndef CADICAL_QUIET
505 replaced++;
506#endif
507 LOG (c, "first substituted literal %d in", substituted);
508
509 // Now copy the result to 'clause'. Substitute literals if they have a
510 // different representative. Skip duplicates and false literals. If a
511 // literal occurs in both phases or is assigned to true the clause is
512 // satisfied and can be marked as garbage.
513
514 CADICAL_assert (clause.empty ());
515 CADICAL_assert (lrat_chain.empty ());
516 CADICAL_assert (analyzed.empty ());
517 bool satisfied = false;
518
519 for (int k = 0; !satisfied && k < size; k++) {
520 const int lit = c->literals[k];
521 signed char tmp = val (lit);
522 if (tmp > 0)
523 satisfied = true;
524 else if (tmp < 0) {
525 if (!lrat)
526 continue;
527 Flags &f = flags (lit);
528 if (f.seen)
529 continue;
530 f.seen = true;
531 analyzed.push_back (lit);
532 int64_t id = unit_id (-lit);
533 lrat_chain.push_back (id);
534 continue;
535 } else {
536 const int other = reprs[vlit (lit)];
537 tmp = val (other);
538 if (tmp < 0) {
539 if (!lrat)
540 continue;
541 Flags &f = flags (other);
542 if (!f.seen) {
543 f.seen = true;
544 analyzed.push_back (other);
545 int64_t id = unit_id (-other);
546 lrat_chain.push_back (id);
547 }
548 if (other == lit)
549 continue;
550 int64_t id = decompose_ids[vlit (-lit)];
551 CADICAL_assert (id);
552 lrat_chain.push_back (id);
553 continue;
554 } else if (tmp > 0)
555 satisfied = true;
556 else {
557 tmp = marked (other);
558 if (tmp < 0)
559 satisfied = true;
560 else if (!tmp) {
561 mark (other);
562 clause.push_back (other);
563 }
564 if (other == lit)
565 continue;
566 if (!lrat)
567 continue;
568 int64_t id = decompose_ids[vlit (-lit)];
569 CADICAL_assert (id);
570 lrat_chain.push_back (id);
571 }
572 }
573 }
574 if (lrat)
575 lrat_chain.push_back (c->id);
577 LOG (lrat_chain, "lrat_chain:");
578 if (satisfied) {
579 LOG (c, "satisfied after substitution (postponed)");
580 postponed_garbage.push_back (c);
581#ifndef CADICAL_QUIET
582 garbage++;
583#endif
584 } else if (!clause.size ()) {
585 LOG ("learned empty clause during decompose");
587 } else if (clause.size () == 1) {
588 LOG (c, "unit %d after substitution", clause[0]);
589 assign_unit (clause[0]);
590 mark_garbage (c);
591 new_unit = true;
592#ifndef CADICAL_QUIET
593 garbage++;
594#endif
595 } else if (c->literals[0] != clause[0] || c->literals[1] != clause[1]) {
596 LOG ("need new clause since at least one watched literal changed");
597 if (clause.size () == 2)
598 new_binary_clause = true;
599 size_t d_clause_idx = clauses.size ();
600 Clause *d = new_clause_as (c);
601 CADICAL_assert (clauses[d_clause_idx] == d);
602 clauses[d_clause_idx] = c;
603 clauses[i] = d;
604 mark_garbage (c);
605#ifndef CADICAL_QUIET
606 garbage++;
607#endif
608 } else {
609 LOG ("simply shrinking clause since watches did not change");
610 CADICAL_assert (c->size > 2);
611 if (!c->redundant)
612 mark_removed (c);
613 if (proof) {
614 proof->add_derived_clause (++clause_id, c->redundant, clause,
615 lrat_chain);
616 proof->delete_clause (c);
617 c->id = clause_id;
618 }
619 size_t l;
620 int *literals = c->literals;
621 for (l = 2; l < clause.size (); l++)
622 literals[l] = clause[l];
623 int flushed = c->size - (int) l;
624 if (flushed) {
625 if (l == 2)
626 new_binary_clause = true;
627 LOG ("flushed %d literals", flushed);
628 (void) shrink_clause (c, l);
629 } else if (likely_to_be_kept_clause (c))
630 mark_added (c);
631 // we have shrunken c->size to l so even though there is an CADICAL_assertion
632 // for c->size > 2 at the beginning of this else block, the new size
633 // can be 2 now.
634 if (c->size == 2) { // cheaper to update only new binary clauses
635 CADICAL_assert (new_binary_clause);
636 update_watch_size (watches (c->literals[0]), c->literals[1], c);
637 update_watch_size (watches (c->literals[1]), c->literals[0], c);
638 }
639 LOG (c, "substituted");
640 }
641 while (!clause.empty ()) {
642 int lit = clause.back ();
643 clause.pop_back ();
644 CADICAL_assert (marked (lit) > 0);
645 unmark (lit);
646 }
647 lrat_chain.clear ();
648 }
649
650 if (proof) {
651 for (auto idx : vars) {
652 if (!substituted)
653 break;
654 if (!active (idx))
655 continue;
656 const int64_t id1 = decompose_ids[vlit (-idx)];
657 if (!id1)
658 continue;
659 int other = reprs[vlit (idx)];
660 CADICAL_assert (other != idx);
661 CADICAL_assert (!flags (other).eliminated ());
662 CADICAL_assert (!flags (other).substituted ());
663
664 clause.push_back (other);
665 clause.push_back (-idx);
666 proof->delete_clause (id1, false, clause);
667 clause.clear ();
668
669 clause.push_back (idx);
670 clause.push_back (-other);
671 const int64_t id2 = decompose_ids[vlit (idx)];
672 proof->delete_clause (id2, false, clause);
673 clause.clear ();
674 }
675 }
676
677 if (!unsat && !postponed_garbage.empty ()) {
678 LOG ("now marking %zd postponed garbage clauses",
679 postponed_garbage.size ());
680 for (const auto &c : postponed_garbage)
681 mark_garbage (c);
682 }
683 erase_vector (postponed_garbage);
684
685 PHASE ("decompose", stats.decompositions,
686 "%zd clauses replaced %.2f%% producing %zd garbage clauses %.2f%%",
687 replaced, percent (replaced, clauses_size), garbage,
688 percent (garbage, replaced));
689
690 erase_vector (scc);
691
692 // Propagate found units.
693
694 if (!unsat && propagated < trail.size () && !propagate ()) {
695 LOG ("empty clause after propagating units from substitution");
697 }
698
699 for (auto idx : vars) {
700 if (!substituted)
701 break;
702 if (unsat)
703 break;
704 if (!active (idx))
705 continue;
706 int other = reprs[vlit (idx)];
707 if (other == idx)
708 continue;
709 CADICAL_assert (!flags (other).eliminated ());
710 CADICAL_assert (!flags (other).substituted ());
711 if (!flags (other).fixed ())
712 mark_substituted (idx);
713 }
714
715 reprs_delete.free ();
716 dfs_delete.free ();
717 erase_vector (dfs_chains);
718
719 if (substituted)
720 flush_all_occs_and_watches (); // particularly the 'blit's
721
722 bool success =
723 unsat || (substituted > 0 && (new_unit || new_binary_clause));
724 report ('d', !opts.reportall && !success);
725
727
728 return success;
729}
730
732 for (int round = 1; round <= opts.decomposerounds; round++)
733 if (!decompose_round ())
734 break;
735}
736
737} // namespace CaDiCaL
738
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
Definition global.h:14
#define LOG(...)
#define TRAVERSED
Definition decompose.hpp:16
Cube * p
Definition exorList.c:222
#define PHASE(...)
Definition message.hpp:52
const char * flags()
void clear_n(T *base, size_t n)
Definition util.hpp:149
void update_watch_size(Watches &ws, int blit, Clause *conflict)
Definition watch.hpp:63
vector< Watch > Watches
Definition watch.hpp:45
void erase_vector(std::vector< T > &v)
Definition util.hpp:90
double percent(double a, double b)
Definition util.hpp:21
#define START_SIMPLIFIER(S, M)
Definition profile.hpp:172
#define STOP_SIMPLIFIER(S, M)
Definition profile.hpp:197
int lit
Definition satVec.h:130
unsigned min
Definition decompose.hpp:20
unsigned idx
Definition decompose.hpp:19
Clause * parent
Definition decompose.hpp:21
External * external
Definition internal.hpp:312
void mark_decomposed(int lit)
vector< int > analyzed
Definition internal.hpp:267
void mark_garbage(Clause *)
vector< int64_t > lrat_chain
Definition internal.hpp:210
void report(char type, int verbose_level=0)
void decompose_analyze_binary_chain(DFS *dfs, int)
void unmark(int lit)
Definition internal.hpp:490
void implied(std::vector< int > &entrailed)
Flags & flags(int lit)
Definition internal.hpp:454
vector< int > trail
Definition internal.hpp:259
int fixed(int lit)
bool terminated_asynchronously(int factor=1)
void mark_removed(int lit)
void mark_substituted(int)
bool frozen(int lit)
signed char val(int lit) const
signed char marked(int lit) const
Definition internal.hpp:478
int64_t unit_id(int lit) const
Definition internal.hpp:434
vector< int > sign_marked
Definition internal.hpp:269
bool active(int lit)
Definition internal.hpp:360
unsigned vlit(int lit) const
Definition internal.hpp:408
void build_lrat_for_clause(const vector< vector< Clause * > > &dfs_chains, bool invert=false)
vector< Clause * > clauses
Definition internal.hpp:283
const Range vars
Definition internal.hpp:324
vector< Clause * > decompose_analyze_binary_clauses(DFS *dfs, int from)
void decompose_conflicting_scc_lrat(DFS *dfs, vector< int > &)
size_t shrink_clause(Clause *, int new_size)
int active() const
Definition internal.hpp:362
void mark_added(int lit, int size, bool redundant)
bool marked_decomposed(int lit)
Clause * new_clause_as(const Clause *orig)
void unmark_decomposed(int lit)
vector< int64_t > mini_chain
Definition internal.hpp:211
Watches & watches(int lit)
Definition internal.hpp:467
bool likely_to_be_kept_clause(Clause *c)
vector< int > clause
Definition internal.hpp:260
unsigned size
Definition vector.h:35
signed char mark
Definition value.h:8
vector watches
Definition watch.h:49