ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
cadical_factor.cpp
Go to the documentation of this file.
1#include "global.h"
2
3#include "internal.hpp"
4
6
7namespace CaDiCaL {
8
9#define FACTORS 1
10#define QUOTIENT 2
11#define NOUNTED 4
12
13inline bool factor_occs_size::operator() (unsigned a, unsigned b) {
14 size_t s = internal->occs (internal->u2i (a)).size ();
15 size_t t = internal->occs (internal->u2i (b)).size ();
16 if (s > t)
17 return true;
18 if (s < t)
19 return false;
20 return a > b;
21}
22
23// do full occurence list as in elim.cpp but filter out useless clauses
26
28 init_occs ();
29
30 const int size_limit = opts.factorsize;
31
32 vector<unsigned> bincount, largecount;
33 const unsigned max_lit = 2 * (max_var + 1);
34 enlarge_zero (bincount, max_lit);
35 if (size_limit > 2)
36 enlarge_zero (largecount, max_lit);
37
38 vector<Clause *> candidates;
39 int64_t &ticks = stats.ticks.factor;
40 ticks += 1 + cache_lines (clauses.size (), sizeof (Clause *));
41
42 // push binary clauses on the occurrence stack.
43 for (const auto &c : clauses) {
44 ticks++;
45 if (c->garbage)
46 continue;
47 if (c->redundant && c->size > 2)
48 continue;
49 if (c->size > size_limit)
50 continue;
51 if (c->size == 2) {
52 const int lit = c->literals[0];
53 const int other = c->literals[1];
54 bincount[vlit (lit)]++;
55 bincount[vlit (other)]++;
56 occs (lit).push_back (c);
57 occs (other).push_back (c);
58 continue;
59 }
60 candidates.push_back (c);
61 for (const auto &lit : *c) {
62 largecount[vlit (lit)]++;
63 }
64 }
65 if (size_limit == 2)
66 return;
67
68 // iterate counts of larger clauses rounds often
69 const unsigned rounds = opts.factorcandrounds;
70 unsigned candidates_before = 0;
71 for (unsigned round = 1; round <= rounds; round++) {
72 LOG ("factor round %d", round);
73 if (candidates.size () == candidates_before)
74 break;
75 ticks += 1 + cache_lines (candidates.size (), sizeof (Clause *));
76 candidates_before = candidates.size ();
77 vector<unsigned> newlargecount;
78 enlarge_zero (newlargecount, max_lit);
79 const auto begin = candidates.begin ();
80 auto p = candidates.begin ();
81 auto q = p;
82 const auto end = candidates.end ();
83 while (p != end) {
84 Clause *c = *q++ = *p++;
85 ticks++;
86 for (const auto &lit : *c) {
87 const auto idx = vlit (lit);
88 if (bincount[idx] + largecount[idx] < 2) {
89 q--;
90 goto CONTINUE_WITH_NEXT_CLAUSE;
91 }
92 }
93 for (const auto &lit : *c) {
94 const auto idx = vlit (lit);
95 newlargecount[idx]++;
96 }
97 CONTINUE_WITH_NEXT_CLAUSE:
98 continue;
99 }
100 candidates.resize (q - begin);
101 largecount.swap (newlargecount);
102 }
103
104 // finally push remaining clause on the occurrence stack
105 for (const auto &c : candidates)
106 for (const auto &lit : *c)
107 occs (lit).push_back (c);
108}
109
110// go back to two watch scheme
116
118 : internal (i), limit (l), schedule (i) {
119 const unsigned max_var = internal->max_var;
120 const unsigned max_lit = 2 * (max_var + 1);
121 initial = max_var;
122 bound = internal->lim.elimbound;
123 enlarge_zero (count, max_lit);
124 quotients.first = quotients.last = 0;
125}
126
128 CADICAL_assert (counted.empty ());
129 CADICAL_assert (nounted.empty ());
130 CADICAL_assert (flauses.empty ());
131 internal->release_quotients (*this);
132 schedule.erase (); // actually not necessary
133}
134
136 double res = occs (lit).size ();
137 LOG ("watches score %g of %d", res, lit);
138 return res;
139}
140
141// the marks in cadical have 6 bits for marking but work on idx
142// to mark everything (FACTORS, QUOTIENT, NOUNTED) we shift the bits
143// depending on the sign of factor (+ bitmask)
144// i.e. if factor is positive, we apply a bitmask to only get
145// the first three bits (& 7u)
146// otherwise we leftshift by 3 (>> 3) to get the bits 4,5,6
147// use markfact, unmarkfact, getfact for this purpose.
148//
152 Quotient *res = new Quotient (factor);
153 res->next = 0;
154 res->matched = 0;
156 res->bid = 0;
157 if (last) {
159 CADICAL_assert (!last->next);
160 last->next = res;
161 res->id = last->id + 1;
162 } else {
165 res->id = 0;
166 }
168 res->prev = last;
169 LOG ("new quotient[%zu] with factor %d", res->id, factor);
170 return res;
171}
172
174 for (Quotient *q = factoring.quotients.first, *next; q; q = next) {
175 next = q->next;
176 int factor = q->factor;
179 delete q;
180 }
182}
183
187 vector<Clause *> &qlauses = quotient->qlauses;
188 int64_t ticks = 0;
189 for (const auto &c : occs (factor)) {
190 qlauses.push_back (c);
191 ticks++;
192 }
193 size_t res = qlauses.size ();
194 LOG ("quotient[0] factor %d size %zu", factor, res);
195 // This invariant can of course be broken by previous factorings
196 // CADICAL_assert (res > 1);
197 stats.ticks.factor += ticks;
198 return res;
199}
200
202 for (const auto &lit : nounted) {
205 }
206 nounted.clear ();
207}
208
210 for (auto c : flauses) {
211 CADICAL_assert (c->swept);
212 c->swept = false;
213 }
214 flauses.clear ();
215}
216
218 size_t *best_reduction_ptr) {
219 size_t factors = 1, best_reduction = 0;
220 Quotient *best = 0;
221 for (Quotient *q = factoring.quotients.first; q; q = q->next) {
222 size_t quotients = q->qlauses.size ();
223 size_t before_factorization = quotients * factors;
224 size_t after_factorization = quotients + factors;
225 if (before_factorization == after_factorization)
226 LOG ("quotient[%zu] factors %zu clauses into %zu thus no change",
227 factors - 1, before_factorization, after_factorization);
228 else if (before_factorization < after_factorization)
229 LOG ("quotient[%zu] factors %zu clauses into %zu thus %zu more",
230 factors - 1, before_factorization, after_factorization,
231 after_factorization - before_factorization);
232 else {
233 size_t delta = before_factorization - after_factorization;
234 LOG ("quotient[%zu] factors %zu clauses into %zu thus %zu less",
235 factors - 1, before_factorization, after_factorization, delta);
236 if (!best || best_reduction < delta) {
237 best_reduction = delta;
238 best = q;
239 }
240 }
241 factors++;
242 }
243 if (!best) {
244 LOG ("no decreasing quotient found");
245 return 0;
246 }
247 LOG ("best decreasing quotient[%zu] with reduction %zu", best->id,
248 best_reduction);
249 *best_reduction_ptr = best_reduction;
250 return best;
251}
252
253int Internal::next_factor (Factoring &factoring, unsigned *next_count_ptr) {
254 Quotient *last_quotient = factoring.quotients.last;
255 CADICAL_assert (last_quotient);
256 vector<Clause *> &last_clauses = last_quotient->qlauses;
258 vector<int> &counted = factoring.counted;
259 vector<Clause *> &flauses = factoring.flauses;
260 CADICAL_assert (counted.empty ());
261 CADICAL_assert (flauses.empty ());
262 const int initial = factoring.initial;
263 int64_t ticks = 1 + cache_lines (last_clauses.size (), sizeof (Clause *));
264 for (auto c : last_clauses) {
265 CADICAL_assert (!c->swept);
266 int min_lit = 0;
267 unsigned factors = 0;
268 size_t min_size = 0;
269 ticks++;
270 for (const auto &other : *c) {
271 if (getfact (other, FACTORS)) {
272 if (factors++)
273 break;
274 } else {
275 CADICAL_assert (!getfact (other, QUOTIENT));
276 markfact (other, QUOTIENT);
277 const size_t other_size = occs (other).size ();
278 if (!min_lit || other_size < min_size) {
279 min_lit = other;
280 min_size = other_size;
281 }
282 }
283 }
284 CADICAL_assert (factors);
285 if (factors == 1) {
286 CADICAL_assert (min_lit);
287 const int c_size = c->size;
288 vector<int> &nounted = factoring.nounted;
289 CADICAL_assert (nounted.empty ());
290 ticks += 1 + cache_lines (occs (min_lit).size (), sizeof (Clause *));
291 for (auto d : occs (min_lit)) {
292 if (c == d)
293 continue;
294 ticks++;
295 if (d->swept)
296 continue;
297 if (d->size != c_size)
298 continue;
299 int next = 0;
300 for (const auto &other : *d) {
301 if (getfact (other, QUOTIENT))
302 continue;
303 if (getfact (other, FACTORS))
304 goto CONTINUE_WITH_NEXT_MIN_WATCH;
305 if (getfact (other, NOUNTED))
306 goto CONTINUE_WITH_NEXT_MIN_WATCH;
307 if (next)
308 goto CONTINUE_WITH_NEXT_MIN_WATCH;
309 next = other;
310 }
311 CADICAL_assert (next);
312 if (abs (next) > abs (initial))
313 continue;
314 if (!active (next))
315 continue;
316 CADICAL_assert (!getfact (next, FACTORS));
317 CADICAL_assert (!getfact (next, NOUNTED));
318 markfact (next, NOUNTED);
319 nounted.push_back (next);
320 d->swept = true;
321 flauses.push_back (d);
322 if (!count[vlit (next)])
323 counted.push_back (next);
324 count[vlit (next)]++;
325 CONTINUE_WITH_NEXT_MIN_WATCH:;
326 }
327 clear_nounted (nounted);
328 }
329 for (const auto &other : *c)
330 if (getfact (other, QUOTIENT))
331 unmarkfact (other, QUOTIENT);
332 stats.ticks.factor += ticks;
333 ticks = 0;
334 if (stats.ticks.factor > factoring.limit)
335 break;
336 }
337 clear_flauses (flauses);
338 unsigned next_count = 0;
339 int next = 0;
340 if (stats.ticks.factor <= factoring.limit) {
341 unsigned ties = 0;
342 for (const auto &lit : counted) {
343 const unsigned lit_count = count[vlit (lit)];
344 if (lit_count < next_count)
345 continue;
346 if (lit_count == next_count) {
347 CADICAL_assert (lit_count);
348 ties++;
349 } else {
350 CADICAL_assert (lit_count > next_count);
351 next_count = lit_count;
352 next = lit;
353 ties = 1;
354 }
355 }
356 if (next_count < 2) {
357 LOG ("next factor count %u smaller than 2", next_count);
358 next = 0;
359 } else if (ties > 1) {
360 LOG ("found %u tied next factor candidate literals with count %u",
361 ties, next_count);
362 double next_score = -1;
363 for (const auto &lit : counted) {
364 const unsigned lit_count = count[vlit (lit)];
365 if (lit_count != next_count)
366 continue;
367 double lit_score = tied_next_factor_score (lit);
368 CADICAL_assert (lit_score >= 0);
369 LOG ("score %g of next factor candidate %d", lit_score, lit);
370 if (lit_score <= next_score)
371 continue;
372 next_score = lit_score;
373 next = lit;
374 }
375 CADICAL_assert (next_score >= 0);
376 CADICAL_assert (next);
377 LOG ("best score %g of next factor %d", next_score, next);
378 } else {
379 CADICAL_assert (ties == 1);
380 LOG ("single next factor %d with count %u", next, next_count);
381 }
382 }
383 for (const auto &lit : counted)
384 count[vlit (lit)] = 0;
385 counted.clear ();
386 CADICAL_assert (!next || next_count > 1);
387 *next_count_ptr = next_count;
388 return next;
389}
390
392 unsigned expected_next_count) {
393 Quotient *last_quotient = factoring.quotients.last;
394 Quotient *next_quotient = new_quotient (factoring, next);
395
396 CADICAL_assert (last_quotient);
397 vector<Clause *> &last_clauses = last_quotient->qlauses;
398 vector<Clause *> &next_clauses = next_quotient->qlauses;
399 vector<size_t> &matches = next_quotient->matches;
400 vector<Clause *> &flauses = factoring.flauses;
401 CADICAL_assert (flauses.empty ());
402
403 int64_t ticks = 1 + cache_lines (last_clauses.size (), sizeof (Clause *));
404
405 size_t i = 0;
406
407 for (auto c : last_clauses) {
408 CADICAL_assert (!c->swept);
409 int min_lit = 0;
410 unsigned factors = 0;
411 size_t min_size = 0;
412 ticks++;
413 for (const auto &other : *c) {
414 if (getfact (other, FACTORS)) {
415 if (factors++)
416 break;
417 } else {
418 CADICAL_assert (!getfact (other, QUOTIENT));
419 markfact (other, QUOTIENT);
420 const size_t other_size = occs (other).size ();
421 if (!min_lit || other_size < min_size) {
422 min_lit = other;
423 min_size = other_size;
424 }
425 }
426 }
427 CADICAL_assert (factors);
428 if (factors == 1) {
429 CADICAL_assert (min_lit);
430 const int c_size = c->size;
431 ticks += 1 + cache_lines (occs (min_lit).size (), sizeof (Clause *));
432 for (auto d : occs (min_lit)) {
433 if (c == d)
434 continue;
435 ticks++;
436 if (d->swept)
437 continue;
438 if (d->size != c_size)
439 continue;
440 for (const auto &other : *d) {
441 if (getfact (other, QUOTIENT))
442 continue;
443 if (other != next)
444 goto CONTINUE_WITH_NEXT_MIN_WATCH;
445 }
446 LOG (c, "matched");
447 LOG (d, "keeping");
448
449 next_clauses.push_back (d);
450 matches.push_back (i);
451 flauses.push_back (d);
452 d->swept = true;
453 break;
454
455 CONTINUE_WITH_NEXT_MIN_WATCH:;
456 }
457 }
458 for (const auto &other : *c)
459 if (getfact (other, QUOTIENT))
460 unmarkfact (other, QUOTIENT);
461 i++;
462 }
463 clear_flauses (flauses);
464 stats.ticks.factor += ticks;
465
466 CADICAL_assert (expected_next_count <= next_clauses.size ());
467 (void) expected_next_count;
468}
469
470// We only need to enlarge factoring.count as everything else is
471// initialized in internal
473 CADICAL_assert (lit > 0);
474 size_t new_var_size = lit + 1;
475 size_t new_lit_size = 2 * new_var_size;
476 enlarge_zero (factoring.count, new_lit_size);
477}
478
480 Quotient *prev = q->prev;
481 vector<size_t> &q_matches = q->matches, &prev_matches = prev->matches;
482 vector<Clause *> &q_clauses = q->qlauses, &prev_clauses = prev->qlauses;
483 const size_t n = q_clauses.size ();
484 CADICAL_assert (n == q_matches.size ());
485 bool prev_is_first = !prev->id;
486 size_t i = 0;
487 while (i < q_matches.size ()) {
488 size_t j = q_matches[i];
489 q_matches[i] = i;
490 CADICAL_assert (i <= j);
491 if (!prev_is_first) {
492 size_t matches = prev_matches[j];
493 prev_matches[i] = matches;
494 }
495 Clause *c = prev_clauses[j];
496 prev_clauses[i] = c;
497 i++;
498 }
499 LOG ("flushing %zu clauses of quotient[%zu]", prev_clauses.size () - n,
500 prev->id);
501 if (!prev_is_first)
502 prev_matches.resize (n);
503 prev_clauses.resize (n);
504}
505
506// special case when we have two quotients with negated factors.
507// in this case, factoring does not make sense, and instead we
508// can resolve the clauses of the two quotients.
509// this subsumes all clauses in all quotients.
511 const int factor = q->factor;
512 const int not_factor = p->factor;
513 CADICAL_assert (-factor == not_factor);
514 LOG (
515 "adding self subsuming factor because blocked clause is a tautology");
516 for (auto c : q->qlauses) {
517 for (const auto &lit : *c) {
518 if (lit == factor)
519 continue;
520 clause.push_back (lit);
521 }
522 if (lrat) {
523 for (auto d : p->qlauses) {
524 bool match = true;
525 for (const auto &lit : *d) {
526 if (lit == not_factor)
527 continue;
528 if (std::find (clause.begin (), clause.end (), lit) ==
529 clause.end ()) {
530 match = false;
531 break;
532 }
533 }
534 if (match) {
535 lrat_chain.push_back (d->id);
536 break;
537 }
538 }
539 lrat_chain.push_back (c->id);
540 CADICAL_assert (lrat_chain.size () == 2);
541 }
542 if (clause.size () > 1) {
544 } else {
545 const int unit = clause[0];
546 const signed char tmp = val (unit);
547 if (!tmp)
548 assign_unit (unit);
549 else if (tmp < 0) {
550 if (lrat) {
551 int64_t id = unit_id (-unit);
552 lrat_chain.push_back (id);
553 std::reverse (lrat_chain.begin (), lrat_chain.end ());
554 }
556 clause.clear ();
557 lrat_chain.clear ();
558 break;
559 }
560 }
561 clause.clear ();
562 lrat_chain.clear ();
563 }
564}
565
567 Quotient *x = 0, *y = 0;
568 bool found = false;
569 for (Quotient *p = q; p; p = p->prev) {
570 const int factor = p->factor;
571 Flags &f = flags (factor);
572 if (f.seen) {
573 CADICAL_assert (std::find (analyzed.begin (), analyzed.end (), -factor) !=
574 analyzed.end ());
575 found = true;
576 x = p;
577 for (Quotient *r = q; r; r = r->prev) {
578 if (r->factor != -factor)
579 continue;
580 y = r;
581 break;
582 }
583 break;
584 }
585 analyzed.push_back (factor);
586 f.seen = true;
587 }
588 CADICAL_assert (!found || (x && y));
590 if (found) {
592 return true;
593 }
594 return false;
595}
596
597// this is a pure binary clauses containing fresh and one other literal
598// it is added for all applicable quotients.
600 const int factor = q->factor;
601 LOG ("factored %d divider %d", factor, fresh);
602 clause.push_back (factor);
603 clause.push_back (fresh);
605 clause.clear ();
606 if (lrat)
607 mini_chain.push_back (-clause_id);
608}
609
610// this clause is blocked on fresh, i.e., it contains all literals from
611// the binaries above, but negated. This is only added to the proof, to
612// make checking easier.
613void Internal::blocked_clause (Quotient *q, int not_fresh) {
614 if (!proof)
615 return;
616 int64_t new_id = ++clause_id;
617 q->bid = new_id;
618 CADICAL_assert (clause.empty ());
619 for (Quotient *p = q; p; p = p->prev)
620 clause.push_back (-p->factor);
621 clause.push_back (not_fresh);
622 CADICAL_assert (!lrat || mini_chain.size ());
623 proof->add_derived_clause (new_id, true, clause, mini_chain);
624 mini_chain.clear ();
625 clause.clear ();
626}
627
628// this is the other side of the factored clauses. To derive these,
629// one can resolved the blocked clause on all matching clauses of
630// one type
632 LOG ("adding factored quotient[%zu] clauses", q->id);
633 const int factor = q->factor;
634 CADICAL_assert (lrat_chain.empty ());
635 auto qlauses = q->qlauses;
636 for (unsigned idx = 0; idx < qlauses.size (); idx++) {
637 const auto c = qlauses[idx];
638 CADICAL_assert (clause.empty ());
639 for (const auto &other : *c) {
640 if (other == factor) {
641 continue;
642 }
643 clause.push_back (other);
644 }
645 if (lrat) {
647 CADICAL_assert (q->bid);
648 unsigned idxtoo = idx;
649 for (Quotient *p = q; p; p = p->prev) {
650 lrat_chain.push_back (p->qlauses[idxtoo]->id);
651 if (p->prev)
652 idxtoo = p->matches[idx];
653 }
654 lrat_chain.push_back (q->bid);
655 }
656 clause.push_back (not_fresh);
658 clause.clear ();
659 lrat_chain.clear ();
660 }
661 if (proof) {
662 for (Quotient *p = q; p; p = p->prev) {
663 clause.push_back (-p->factor);
664 }
665 clause.push_back (not_fresh);
666 proof->delete_clause (q->bid, true, clause);
667 clause.clear ();
668 }
669}
670
671// remove deleted clauses once factored.
673 for (const auto &lit : *c) {
674 auto &occ = occs (lit);
675 auto p = occ.begin ();
676 auto q = occ.begin ();
677 auto begin = occ.begin ();
678 auto end = occ.end ();
679 while (p != end) {
680 *q = *p++;
681 if (*q != c)
682 q++;
683 }
684 CADICAL_assert (q + 1 == p);
685 occ.resize (q - begin);
686 }
687}
688
689// delete the factored clauses
691 LOG ("deleting unfactored quotient[%zu] clauses", q->id);
692 for (auto c : q->qlauses) {
694 mark_garbage (c);
695 stats.literals_unfactored += c->size;
696 stats.clauses_unfactored++;
697 }
698}
699
700// update the priority queue for scheduling
702 const int factor = q->factor;
705 for (auto c : q->qlauses) {
706 LOG (c, "deleting unfactored");
707 for (const auto &lit : *c)
708 if (lit != factor)
710 }
711}
712
714 for (Quotient *p = q; p->prev; p = p->prev)
716 if (self_subsuming_factor (q)) {
717 for (Quotient *p = q; p; p = p->prev)
719 for (Quotient *p = q; p; p = p->prev)
721 return true;
722 }
723 const int fresh = get_new_extension_variable ();
724 if (!fresh)
725 return false;
726 stats.factored++;
727 factoring.fresh.push_back (fresh);
728 for (Quotient *p = q; p; p = p->prev)
729 add_factored_divider (p, fresh);
730 const int not_fresh = -fresh;
731 blocked_clause (q, not_fresh);
732 add_factored_quotient (q, not_fresh);
733 for (Quotient *p = q; p; p = p->prev)
735 for (Quotient *p = q; p; p = p->prev)
737 CADICAL_assert (fresh > 0);
739 return true;
740}
741
744 const size_t size = occs (lit).size ();
745 const unsigned idx = vlit (lit);
746 if (schedule.contains (idx))
747 schedule.update (idx);
748 else if (size > 1) {
749 schedule.push_back (idx);
750 }
751}
752
754 for (const auto &idx : vars) {
755 if (active (idx)) {
756 Flags &f = flags (idx);
757 const int lit = idx;
758 const int not_lit = -lit;
759 if (f.factor & 1)
761 if (f.factor & 2)
763 }
764 }
765#ifndef CADICAL_QUIET
766 size_t size_cands = factoring.schedule.size ();
767 VERBOSE (2, "scheduled %zu factorization candidate literals %.0f %%",
768 size_cands, percent (size_cands, max_var));
769#endif
770}
771
775 bool done = false;
776#ifndef CADICAL_QUIET
777 unsigned factored = 0;
778#endif
779 int64_t *ticks = &stats.ticks.factor;
780 VERBOSE (3, "factorization limit of %" PRIu64 " ticks", limit - *ticks);
781
782 while (!unsat && !done && !factoring.schedule.empty ()) {
783 const unsigned ufirst = factoring.schedule.pop_front ();
784 LOG ("next factor candidate %d", ufirst);
785 const int first = u2i (ufirst);
786 const int first_idx = vidx (first);
787 if (!active (first_idx))
788 continue;
789 if (!occs (first).size ()) {
790 factoring.schedule.clear ();
791 break;
792 }
793 if (*ticks > limit) {
794 VERBOSE (2, "factorization ticks limit hit");
795 break;
796 }
798 break;
799 Flags &f = flags (first_idx);
800 const unsigned bit = 1u << (first < 0);
801 if (!(f.factor & bit))
802 continue;
803 f.factor &= ~bit;
804 const size_t first_count = first_factor (factoring, first);
805 if (first_count > 1) {
806 for (;;) {
807 unsigned next_count;
808 const int next = next_factor (factoring, &next_count);
809 if (next == 0)
810 break;
811 CADICAL_assert (next_count > 1);
812 if (next_count < 2)
813 break;
814 factorize_next (factoring, next, next_count);
815 }
816 size_t reduction;
817 Quotient *q = best_quotient (factoring, &reduction);
818 if (q && (int) reduction > factoring.bound) {
819 if (apply_factoring (factoring, q)) {
820#ifndef CADICAL_QUIET
821 factored++;
822#endif
823 } else
824 done = true;
825 }
826 }
828 }
829
830 // since we cannot remove elements from the heap we check wether the
831 // first element in the heap has occurences
832 bool completed = factoring.schedule.empty ();
833 if (!completed) {
834 const unsigned idx = factoring.schedule.front ();
835 completed = occs (u2i (idx)).empty ();
836 }
837 // kissat initializes scores for new variables at this point, however
838 // this is actually done already during resize of internal
839#ifndef CADICAL_QUIET
840 report ('f', !factored);
841#endif
842 return completed;
843}
844
846 const int current_max_external = external->max_var;
847 const int new_external = current_max_external + 1;
848 const int new_internal = external->internalize (new_external, true);
849 // one sideeffect of internalize is enlarging the internal datastructures
850 // which can initialize the watches (wtab)
851 if (watching ())
852 reset_watches ();
853 // it does not enlarge otab, however, so we do this manually
854 init_occs ();
855 CADICAL_assert (vlit (new_internal));
856 return new_internal;
857}
858
860 if (unsat)
861 return false;
863 return false;
864 if (!opts.factor)
865 return false;
866 // The following CADICAL_assertion fails if there are *only* user propagator
867 // clauses (which are redundant).
868 // CADICAL_assert (stats.mark.factor || clauses.empty ());
869 if (last.factor.marked >= stats.mark.factor) {
870 VERBOSE (3,
871 "factorization skipped as no literals have been"
872 "marked to be added (%" PRIu64 " < %" PRIu64 ")",
873 last.factor.marked, stats.mark.factor);
874 return false;
875 }
877
879 if (!stats.factor)
880 limit += opts.factoriniticks * 1e6;
881
883 stats.factor++;
884
885#ifndef CADICAL_QUIET
886 struct {
887 int64_t variables, clauses, ticks;
888 } before, after, delta;
889 before.variables = stats.variables_extension + stats.variables_original;
890 before.ticks = stats.ticks.factor;
891 before.clauses = stats.current.irredundant;
892#endif
893
894 factor_mode ();
895 bool completed = run_factorization (limit);
897
898 propagated = 0;
899 if (!unsat && !propagate ()) {
901 }
902
903#ifndef CADICAL_QUIET
904 after.variables = stats.variables_extension + stats.variables_original;
905 after.clauses = stats.current.irredundant;
906 after.ticks = stats.ticks.factor;
907 delta.variables = after.variables - before.variables;
908 delta.clauses = before.clauses - after.clauses;
909 delta.ticks = after.ticks - before.ticks;
910 VERBOSE (2, "used %f million factorization ticks", delta.ticks * 1e-6);
911 phase ("factorization", stats.factor,
912 "introduced %" PRId64 " extension variables %.0f%%",
913 delta.variables, percent (delta.variables, before.variables));
914 phase ("factorization", stats.factor,
915 "removed %" PRId64 " irredundant clauses %.0f%%", delta.clauses,
916 percent (delta.clauses, before.clauses));
917#endif
918
919 if (completed)
920 last.factor.marked = stats.mark.factor;
922 return true;
923}
924
925} // namespace CaDiCaL
926
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
Definition global.h:14
#define QUOTIENT
#define NOUNTED
#define FACTORS
#define LOG(...)
bool contains(unsigned e) const
Definition heap.hpp:139
void push_back(unsigned e)
Definition heap.hpp:147
void update(unsigned e)
Definition heap.hpp:182
Cube * p
Definition exorList.c:222
#define SET_EFFORT_LIMIT(LIMIT, NAME, THRESHHOLD)
Definition limit.hpp:131
#define VERBOSE(...)
Definition message.hpp:58
const char * flags()
heap< factor_occs_size > FactorSchedule
Definition factor.hpp:33
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
FactorSchedule schedule
Definition factor.hpp:42
vector< int > nounted
Definition factor.hpp:49
vector< unsigned > count
Definition factor.hpp:46
struct CaDiCaL::Factoring::@045300102074365064333035263007161374160235131045 quotients
vector< int > counted
Definition factor.hpp:48
Internal * internal
Definition factor.hpp:40
Factoring(Internal *, int64_t)
vector< Clause * > flauses
Definition factor.hpp:50
unsigned char factor
Definition flags.hpp:33
Clause * new_factor_clause()
External * external
Definition internal.hpp:312
int64_t cache_lines(size_t bytes)
Definition internal.hpp:722
vector< int > analyzed
Definition internal.hpp:267
size_t first_factor(Factoring &, int)
Quotient * best_quotient(Factoring &, size_t *)
void mark_garbage(Clause *)
vector< int64_t > lrat_chain
Definition internal.hpp:210
int vidx(int lit) const
Definition internal.hpp:395
void report(char type, int verbose_level=0)
int u2i(unsigned u)
Definition internal.hpp:412
bool run_factorization(int64_t limit)
void factorize_next(Factoring &, int, unsigned)
void phase(int lit)
bool terminated_asynchronously(int factor=1)
void update_factored(Factoring &factoring, Quotient *q)
void eagerly_remove_from_occurences(Clause *c)
bool self_subsuming_factor(Quotient *)
void clear_flauses(vector< Clause * > &)
void resize_factoring(Factoring &factoring, int lit)
bool apply_factoring(Factoring &factoring, Quotient *q)
bool watching() const
Definition internal.hpp:462
void add_factored_quotient(Quotient *, int not_fresh)
signed char val(int lit) const
bool limit(const char *name, int)
void flush_unmatched_clauses(Quotient *)
int64_t unit_id(int lit) const
Definition internal.hpp:434
void schedule_factorization(Factoring &)
Quotient * new_quotient(Factoring &, int)
int next_factor(Factoring &, unsigned *)
void release_quotients(Factoring &)
bool active(int lit)
Definition internal.hpp:360
unsigned vlit(int lit) const
Definition internal.hpp:408
vector< Clause * > clauses
Definition internal.hpp:283
void update_factor_candidate(Factoring &, int)
const Range vars
Definition internal.hpp:324
void blocked_clause(Quotient *q, int)
void add_factored_divider(Quotient *, int)
void unmarkfact(int lit, int fact)
Definition internal.hpp:599
double tied_next_factor_score(int)
Occs & occs(int lit)
Definition internal.hpp:465
void markfact(int lit, int fact)
Definition internal.hpp:580
void add_self_subsuming_factor(Quotient *, Quotient *)
vector< int64_t > mini_chain
Definition internal.hpp:211
void clear_nounted(vector< int > &)
void delete_unfactored(Quotient *q)
bool getfact(int lit, int fact) const
Definition internal.hpp:568
vector< int > clause
Definition internal.hpp:260
void connect_watches(bool irredundant_only=false)
Quotient * next
Definition factor.hpp:27
Quotient * prev
Definition factor.hpp:27
vector< Clause * > qlauses
Definition factor.hpp:28
vector< size_t > matches
Definition factor.hpp:29
bool operator()(unsigned a, unsigned b)
uint64_t limit
Definition factor.c:58
struct factoring::@160277325255143145147274163211332332056211107037 quotients
unsigned initial
Definition factor.c:49
quotient * first
Definition factor.c:60
unsigned bound
Definition factor.c:53
unsigneds nounted
Definition factor.c:56
unsigned * count
Definition factor.c:50
heap schedule
Definition factor.c:62
unsigneds counted
Definition factor.c:55
quotient * last
Definition factor.c:60
unsigneds fresh
Definition factor.c:54
unsigned size
Definition heap.h:22
struct quotient * next
Definition factor.c:30
unsigned size
Definition vector.h:35