11inline unsigned LratChecker::l2u (
int lit) {
14 unsigned res = 2 * (abs (
lit) - 1);
20signed char &LratChecker::mark (
int lit) {
21 const unsigned u = l2u (
lit);
26signed char &LratChecker::checked_lit (
int lit) {
27 const unsigned u = l2u (
lit);
29 return checked_lits[u];
35 const size_t size = imported_clause.size ();
37 const int off =
size ? 1 : 0;
39 sizeof (LratCheckerClause) + (size - off) *
sizeof (int);
40 LratCheckerClause *res = (LratCheckerClause *)
new char[bytes];
43 res->hash = last_hash;
47 res->tautological =
false;
48 int *literals = res->literals, *
p = literals;
50 for (
auto &b : checked_lits)
53 for (
const auto &
lit : imported_clause) {
55 checked_lit (-
lit) =
true;
56 if (checked_lit (
lit)) {
57 LOG (imported_clause,
"LRAT CHECKER clause tautological");
58 res->tautological =
true;
61 for (
const auto &
lit : imported_clause)
62 checked_lit (-
lit) =
false;
80void LratChecker::enlarge_clauses () {
82 const uint64_t new_size_clauses = size_clauses ? 2 * size_clauses : 1;
83 LOG (
"LRAT CHECKER enlarging clauses of checker from %" PRIu64
85 (uint64_t) size_clauses, (uint64_t) new_size_clauses);
86 LratCheckerClause **new_clauses;
87 new_clauses =
new LratCheckerClause *[new_size_clauses];
88 clear_n (new_clauses, new_size_clauses);
89 for (uint64_t i = 0; i < size_clauses; i++) {
90 for (LratCheckerClause *c = clauses[i], *next; c; c = next) {
92 const uint64_t h = reduce_hash (c->hash, new_size_clauses);
93 c->next = new_clauses[h];
98 clauses = new_clauses;
99 size_clauses = new_size_clauses;
104void LratChecker::collect_garbage_clauses () {
108 LOG (
"LRAT CHECKER collecting %" PRIu64
" garbage clauses %.0f%%",
109 num_garbage,
percent (num_garbage, num_clauses));
111 for (LratCheckerClause *c = garbage, *next; c; c = next)
112 next = c->next, delete_clause (c);
121 : internal (i), size_vars (0), concluded (
false), num_clauses (0),
122 num_finalized (0), num_garbage (0), size_clauses (0), clauses (0),
123 garbage (0), last_hash (0), last_id (0), current_id (0) {
128 for (
unsigned n = 0; n < num_nonces; n++) {
129 uint64_t nonce =
random.next ();
136 memset (&stats, 0,
sizeof (stats));
141 LOG (
"connected to internal");
145 LOG (
"LRAT CHECKER delete");
146 for (
size_t i = 0; i < size_clauses; i++)
148 next = c->next, delete_clause (c);
150 next = c->next, delete_clause (c);
156void LratChecker::enlarge_vars (int64_t idx) {
160 int64_t new_size_vars = size_vars ? 2 * size_vars : 2;
161 while (idx >= new_size_vars)
163 LOG (
"LRAT CHECKER enlarging variables of checker from %" PRId64
165 size_vars, new_size_vars);
167 marks.resize (2 * new_size_vars);
168 checked_lits.resize (2 * new_size_vars);
171 size_vars = new_size_vars;
174inline void LratChecker::import_literal (
int lit) {
178 if (idx >= size_vars)
180 imported_clause.push_back (
lit);
183void LratChecker::import_clause (
const vector<int> &c) {
184 for (
const auto &
lit : c)
185 import_literal (
lit);
190uint64_t LratChecker::reduce_hash (uint64_t hash, uint64_t size) {
194 while ((((uint64_t) 1) << shift) > size) {
203uint64_t LratChecker::compute_hash (
const int64_t
id) {
205 unsigned j =
id % num_nonces;
206 uint64_t tmp = nonces[j] * (uint64_t)
id;
207 return last_hash = tmp;
212 LratCheckerClause **res, *c;
213 const uint64_t hash = compute_hash (
id);
214 const uint64_t h = reduce_hash (hash, size_clauses);
215 for (res = clauses + h; (c = *res); res = &c->next) {
216 if (c->hash == hash && c->id ==
id) {
224void LratChecker::insert () {
226 if (num_clauses == size_clauses)
228 const uint64_t h = reduce_hash (compute_hash (last_id), size_clauses);
229 LratCheckerClause *c = new_clause ();
230 c->next = clauses[h];
237bool LratChecker::check_resolution (vector<int64_t> proof_chain) {
238 if (proof_chain.empty ()) {
239 LOG (
"LRAT CHECKER resolution check skipped clause is tautological");
243#ifndef CADICAL_NDEBUG
244 for (
auto &b : checked_lits)
247 if (!proof_chain.
size () || proof_chain.back () < 0)
249 LratCheckerClause *c = *find (proof_chain.back ());
251 for (
int *i = c->literals; i < c->literals + c->size; i++) {
253 checked_lit (
lit) =
true;
256 for (
auto p = proof_chain.end () - 2;
p >= proof_chain.begin ();
p--) {
260 for (
int *i = c->literals; i < c->literals + c->size; i++) {
262 if (!checked_lit (-
lit))
263 checked_lit (
lit) =
true;
265 checked_lit (-
lit) =
false;
268 for (
const auto &
lit : imported_clause) {
269 if (checked_lit (-
lit)) {
270 LOG (
"LRAT CHECKER resolution failed, resolved literal %d in learned "
273 for (
auto &b : checked_lits)
277 if (!checked_lit (
lit)) {
279 checked_lit (
lit) =
true;
281 checked_lit (-
lit) =
true;
284 for (int64_t
lit = 1;
lit < size_vars;
lit++) {
285 bool ok = checked_lit (
lit) && checked_lit (-
lit);
286 ok = ok || (!checked_lit (
lit) && !checked_lit (-
lit));
287 checked_lit (
lit) = checked_lit (-
lit) =
false;
288 if (!ok && !failed) {
289 LOG (
"LRAT CHECKER resolution failed, learned clause does not match "
302bool LratChecker::check (vector<int64_t> proof_chain) {
303 LOG (imported_clause,
"LRAT CHECKER checking clause");
305#ifndef CADICAL_NDEBUG
306 for (
auto &b : checked_lits)
310 for (
const auto &
lit : imported_clause) {
311 checked_lit (-
lit) =
true;
312 if (checked_lit (
lit)) {
313 LOG (imported_clause,
"LRAT CHECKER clause tautological");
322 if (taut || !proof_chain.
size () || proof_chain.back () < 0) {
323 for (
const auto &
lit : imported_clause) {
324 checked_lit (-
lit) =
false;
330 bool checking =
false;
331 for (
auto &
id : proof_chain) {
332 LratCheckerClause *c = *find (
id);
334 LOG (
"LRAT CHECKER LRAT failed. Did not find clause with id %" PRIu64,
338 if (c->tautological) {
339 LOG (
"LRAT CHECKER LRAT failed. Clause with id %" PRId64
344 used_clauses.push_back (c);
346 LOG (
"LRAT CHECKER LRAT failed. Id %" PRId64
347 " was used multiple times",
353 for (
int *i = c->literals; i < c->literals + c->size; i++) {
355 if (checked_lit (-
lit))
357 if (unit && unit !=
lit) {
363 if (unit == INT_MIN) {
364 LOG (
"LRAT CHECKER check failed, found non unit clause %" PRId64,
id);
368 LOG (
"LRAT CHECKER check succeded, clause falsified %" PRId64,
id);
374 checked_lit (unit) =
true;
376 for (
auto &lc : used_clauses) {
379 for (
auto &b : checked_lits)
382 LOG (
"LRAT CHECKER failed, no conflict found");
388bool LratChecker::check_blocked (vector<int64_t> proof_chain) {
389 for (
const auto &
lit : imported_clause) {
390 checked_lit (-
lit) =
true;
393 for (
size_t i = 0; i < size_clauses; i++) {
394 for (LratCheckerClause *c = clauses[i], *next; c; c = next) {
399 if (std::find (proof_chain.begin (), proof_chain.end (), -c->id) !=
400 proof_chain.end ()) {
403 vector<int> candidates;
404 for (
unsigned i = 0; i < c->size; i++) {
405 const int lit = c->literals[i];
406 if (checked_lit (
lit)) {
410 candidates.push_back (
lit);
415 for (
const auto &
lit : imported_clause) {
416 checked_lit (-
lit) =
false;
422 for (
auto &
lit : imported_clause) {
424 std::find (candidates.begin (), candidates.end (), -
lit) ==
432 for (
unsigned i = 0; i < c->size; i++) {
433 const int lit = c->literals[i];
434 if (checked_lit (
lit)) {
441 bool success =
false;
442 for (
const auto &
lit : imported_clause) {
455 LOG (c,
"LRAT CHECKER addition of original clause[%" PRId64
"]",
id);
462 if (!restore &&
id == 1 + current_id)
465 if (size_clauses && !restore) {
469 fputs (
"different clause with id ", stderr);
470 fprintf (stderr,
"%" PRId64,
id);
471 fputs (
" already present\n", stderr);
477 imported_clause.clear ();
485 LOG (c,
"LRAT CHECKER addition of derived clause[%" PRId64
"]",
id);
496 fputs (
"different clause with id ", stderr);
497 fprintf (stderr,
"%" PRId64,
id);
498 fputs (
" already present\n", stderr);
504 if (check (proof_chain) && check_resolution (proof_chain)) {
506 }
else if (check_blocked (proof_chain)) {
510 LOG (proof_chain,
"LRAT CHECKER check failed with chain");
512 for (
const auto &pid : proof_chain) {
513 const int64_t aid = abs (pid);
515 LOG (d->literals, d->size,
"clause[%" PRId64
"]", pid);
519 fputs (
"failed to check derived clause:\n", stderr);
520 for (
const auto &
lit : imported_clause)
521 fprintf (stderr,
"%d ",
lit);
526 imported_clause.clear ();
532 for (
auto &
lit : c) {
533 if (std::find (assumptions.begin (), assumptions.end (), -
lit) !=
536 if (std::find (constraint.begin (), constraint.end (), -
lit) !=
540 fputs (
"clause contains non assumptions or constraint literals\n",
545 delete_clause (
id,
true, c);
546 assumption_clauses.push_back (
id);
553 for (
auto &
lit : c) {
555 if (std::find (constraint.begin (), constraint.end (),
lit) !=
558 constraint.push_back (
lit);
563 assumption_clauses.clear ();
564 assumptions.clear ();
573 fputs (
"already concluded\n", stderr);
581 fputs (
"empty clause not in proof\n", stderr);
586 if (ids.
size () != 1 || assumption_clauses.size () != 1) {
588 fputs (
"expected exactly one assumption clause\n", stderr);
591 if (ids.back () != assumption_clauses.back ()) {
593 fputs (
"conclusion is not an assumption clause\n", stderr);
599 if (constraint.size () != ids.
size ()) {
601 fputs (
"not complete conclusion given for constraint\n", stderr);
602 fputs (
"The constraint contains the literals: ", stderr);
603 for (
auto c : constraint) {
604 fprintf (stderr,
"%d ", c);
607 fputs (
"\nThe ids are: ", stderr);
609 fprintf (stderr,
"%" PRId64
" ", c);
613 for (
auto &
id : ids) {
614 if (std::find (assumption_clauses.begin (), assumption_clauses.end (),
615 id) != assumption_clauses.end ())
618 fputs (
"assumption clause for constraint missing\n", stderr);
626void LratChecker::delete_clause (int64_t
id,
bool,
const vector<int> &c) {
628 LOG (c,
"LRAT CHECKER checking deletion of clause[%" PRId64
"]",
id);
634 for (
const auto &
lit : imported_clause)
636 const int *dp = d->literals;
637 for (
unsigned i = 0; i < d->size; i++) {
641 fputs (
"deleted clause not in proof:\n", stderr);
642 for (
const auto &
lit : imported_clause)
643 fprintf (stderr,
"%d ",
lit);
648 for (
const auto &
lit : imported_clause)
663 if (num_garbage > 0.5 * max ((
size_t) size_clauses, (
size_t) size_vars))
664 collect_garbage_clauses ();
667 fputs (
"deleted clause not in proof:\n", stderr);
668 for (
const auto &
lit : imported_clause)
669 fprintf (stderr,
"%d ",
lit);
673 imported_clause.clear ();
680 LOG (c,
"LRAT CHECKER saving clause[%" PRId64
"] to restore later",
id);
687 for (
const auto &
lit : imported_clause)
689 const int *dp = d->literals;
690 for (
unsigned i = 0; i < d->size; i++) {
694 fputs (
"deleted clause not in proof:\n", stderr);
695 for (
const auto &
lit : imported_clause)
696 fprintf (stderr,
"%d ",
lit);
701 for (
const auto &
lit : imported_clause)
705 fputs (
"weakened clause not in proof:\n", stderr);
706 for (
const auto &
lit : imported_clause)
707 fprintf (stderr,
"%d ",
lit);
711 imported_clause.clear ();
714 sort (begin (e), end (e));
715 clauses_to_reconstruct[id] = e;
719 LOG (c,
"LRAT CHECKER check of restoration of clause[%" PRId64
"]",
id);
720 if (clauses_to_reconstruct.find (
id) == end (clauses_to_reconstruct)) {
722 fputs (
"restoring clauses not deleted previously:\n", stderr);
723 for (
const auto &
lit : c)
724 fprintf (stderr,
"%d ",
lit);
729 sort (begin (e), end (e));
730 const vector<int> &d = clauses_to_reconstruct.find (
id)->second;
736 for (std::vector<int>::size_type i = 0; i < e.
size () && eq; ++i) {
742 fputs (
"restoring clause that is different than the one imported:\n",
744 for (
const auto &
lit : c)
745 fprintf (stderr,
"%d ",
lit);
747 fputs (
"vs:\n", stderr);
748 for (
const auto &
lit : d)
749 fprintf (stderr,
"%d ",
lit);
754 clauses_to_reconstruct.erase (
id);
759 LOG (c,
"LRAT CHECKER checking finalize of clause[%" PRId64
"]",
id);
767 for (
const auto &
lit : imported_clause)
769 const int *dp = d->literals;
770 for (
unsigned i = 0; i < d->size; i++) {
774 fputs (
"deleted clause not in proof:\n", stderr);
775 for (
const auto &
lit : imported_clause)
776 fprintf (stderr,
"%d ",
lit);
781 for (
const auto &
lit : imported_clause)
786 fputs (
"deleted clause not in proof:\n", stderr);
787 for (
const auto &
lit : imported_clause)
788 fprintf (stderr,
"%d ",
lit);
792 imported_clause.clear ();
799 if (num_finalized == num_clauses) {
801 LOG (
"LRAT CHECKER successful finalize check, all clauses have been "
805 fputs (
"finalize check failed ", stderr);
806 fprintf (stderr,
"%" PRIu64, num_clauses);
807 fputs (
" are not finalized", stderr);
817 for (uint64_t i = 0; i < size_clauses; i++)
819 for (
unsigned i = 0; i < c->size; i++)
820 if (abs (c->literals[i]) > max_var)
821 max_var = abs (c->literals[i]);
822 printf (
"p cnf %d %" PRIu64
"\n", max_var, num_clauses);
823 for (uint64_t i = 0; i < size_clauses; i++)
825 for (
unsigned i = 0; i < c->size; i++)
826 printf (
"%d ", c->literals[i]);
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
void report_status(int, int64_t) override
void add_constraint(const vector< int > &) override
void begin_proof(int64_t) override
void weaken_minus(int64_t, const vector< int > &) override
void conclude_unsat(ConclusionType, const vector< int64_t > &) override
void reset_assumptions() override
void add_derived_clause(int64_t, bool, const vector< int > &, const vector< int64_t > &) override
void add_assumption_clause(int64_t, const vector< int > &, const vector< int64_t > &) override
void restore_clause(int64_t, const vector< int > &)
void add_original_clause(int64_t, bool, const vector< int > &, bool restore) override
void connect_internal(Internal *i) override
void add_assumption(int) override
void finalize_clause(int64_t, const vector< int > &) override
void fatal_message_start()
void clear_n(T *base, size_t n)
double percent(double a, double b)