11inline unsigned Checker::l2u (
int lit) {
14 unsigned res = 2 * (abs (
lit) - 1);
20inline signed char Checker::val (
int lit) {
28signed char &Checker::mark (
int lit) {
29 const unsigned u = l2u (
lit);
35 const unsigned u = l2u (
lit);
43 const size_t size = simplified.size ();
45 const size_t bytes =
sizeof (CheckerClause) + (size - 2) *
sizeof (int);
46 CheckerClause *res = (CheckerClause *)
new char[bytes];
47 DeferDeleteArray<char> delete_res ((
char *) res);
49 res->hash = last_hash;
51 int *literals = res->literals, *
p = literals;
52 for (
const auto &
lit : simplified)
58 for (
unsigned i = 0; i < 2; i++) {
59 int lit = literals[i];
62 for (
unsigned j = i + 1; j <
size; j++) {
63 int other = literals[j];
66 swap (literals[i], literals[j]);
72 watcher (literals[0]).push_back (CheckerWatch (literals[1], res));
73 watcher (literals[1]).push_back (CheckerWatch (literals[0], res));
75 delete_res.release ();
91void Checker::enlarge_clauses () {
93 const uint64_t new_size_clauses = size_clauses ? 2 * size_clauses : 1;
94 LOG (
"CHECKER enlarging clauses of checker from %" PRIu64
" to %" PRIu64,
95 (uint64_t) size_clauses, (uint64_t) new_size_clauses);
96 CheckerClause **new_clauses;
97 new_clauses =
new CheckerClause *[new_size_clauses];
98 clear_n (new_clauses, new_size_clauses);
99 for (uint64_t i = 0; i < size_clauses; i++) {
100 for (CheckerClause *c = clauses[i], *next; c; c = next) {
102 const uint64_t h = reduce_hash (c->hash, new_size_clauses);
103 c->next = new_clauses[h];
108 clauses = new_clauses;
109 size_clauses = new_size_clauses;
113 for (
unsigned i = 0; i < c->size; i++)
114 if (val (c->literals[i]) > 0)
125void Checker::collect_garbage_clauses () {
129 for (
size_t i = 0; i < size_clauses; i++) {
130 CheckerClause **
p = clauses + i, *c;
132 if (clause_satisfied (c)) {
145 LOG (
"CHECKER collecting %" PRIu64
" garbage clauses %.0f%%", num_garbage,
146 percent (num_garbage, num_clauses));
148 for (
int lit = -size_vars + 1;
lit < size_vars;
lit++) {
152 const auto end = ws.end ();
153 auto j = ws.begin (), i = j;
154 for (; i != end; i++) {
155 CheckerWatch &w = *i;
161 if (j == ws.begin ())
164 ws.resize (j - ws.begin ());
167 for (CheckerClause *c = garbage, *next; c; c = next)
168 next = c->next, delete_clause (c);
177 : internal (i), size_vars (0), vals (0), inconsistent (
false),
178 num_clauses (0), num_garbage (0), size_clauses (0), clauses (0),
179 garbage (0), next_to_propagate (0), last_hash (0) {
184 for (
unsigned n = 0; n < num_nonces; n++) {
185 uint64_t nonce =
random.next ();
192 memset (&stats, 0,
sizeof (stats));
197 LOG (
"CHECKER connected to internal");
201 LOG (
"CHECKER delete");
204 for (
size_t i = 0; i < size_clauses; i++)
206 next = c->next, delete_clause (c);
208 next = c->next, delete_clause (c);
218void Checker::enlarge_vars (int64_t idx) {
222 int64_t new_size_vars = size_vars ? 2 * size_vars : 2;
223 while (idx >= new_size_vars)
225 LOG (
"CHECKER enlarging variables of checker from %" PRId64
" to %" PRId64
227 size_vars, new_size_vars);
229 signed char *new_vals;
230 new_vals =
new signed char[2 * new_size_vars];
231 clear_n (new_vals, 2 * new_size_vars);
232 new_vals += new_size_vars;
234 memcpy ((
void *) (new_vals - size_vars), (
void *) (vals - size_vars),
239 size_vars = new_size_vars;
241 watchers.resize (2 * new_size_vars);
242 marks.resize (2 * new_size_vars);
247inline void Checker::import_literal (
int lit) {
251 if (idx >= size_vars)
253 simplified.push_back (
lit);
254 unsimplified.push_back (
lit);
257void Checker::import_clause (
const vector<int> &c) {
258 for (
const auto &
lit : c)
259 import_literal (
lit);
264 int c = abs (a), d = abs (b);
273bool Checker::tautological () {
274 sort (simplified.begin (), simplified.end (), lit_smaller ());
275 const auto end = simplified.end ();
276 auto j = simplified.begin ();
278 for (
auto i = j; i != end; i++) {
284 const signed char tmp = val (
lit);
289 simplified.resize (j - simplified.begin ());
295uint64_t Checker::reduce_hash (uint64_t hash, uint64_t size) {
299 while ((((uint64_t) 1) << shift) > size) {
308uint64_t Checker::compute_hash () {
309 unsigned j = last_id % num_nonces;
310 uint64_t tmp = nonces[j] * last_id;
311 return last_hash = tmp;
316 CheckerClause **res, *c;
317 const uint64_t hash = compute_hash ();
318 const unsigned size = simplified.size ();
319 const uint64_t h = reduce_hash (hash, size_clauses);
320 for (
const auto &
lit : simplified)
322 for (res = clauses + h; (c = *res); res = &c->next) {
323 if (c->hash == hash && c->size == size) {
325 const int *literals = c->literals;
326 for (
unsigned i = 0; found && i !=
size; i++)
327 found = mark (literals[i]);
333 for (
const auto &
lit : simplified)
338void Checker::insert () {
340 if (num_clauses == size_clauses)
342 const uint64_t h = reduce_hash (compute_hash (), size_clauses);
343 CheckerClause *c = new_clause ();
344 c->next = clauses[h];
350inline void Checker::assign (
int lit) {
354 trail.push_back (
lit);
357inline void Checker::assume (
int lit) {
358 signed char tmp = val (
lit);
366void Checker::backtrack (
unsigned previously_propagated) {
370 while (trail.size () > previously_propagated) {
371 int lit = trail.back ();
374 vals[
lit] = vals[-
lit] = 0;
378 trail.resize (previously_propagated);
379 next_to_propagate = previously_propagated;
388bool Checker::propagate () {
390 while (res && next_to_propagate < trail.size ()) {
391 int lit = trail[next_to_propagate++];
392 stats.propagations++;
396 const auto end = ws.end ();
397 auto j = ws.begin (), i = j;
398 for (; res && i != end; i++) {
399 CheckerWatch &w = *j++ = *i;
400 const int blit = w.blit;
402 const signed char blit_val = val (blit);
405 const unsigned size = w.size;
413 CheckerClause *c = w.clause;
419 int *lits = c->literals;
420 int other = lits[0] ^ lits[1] ^ (-
lit);
422 signed char other_val = val (other);
427 lits[0] = other, lits[1] = -
lit;
430 signed char replacement_val = -1;
431 for (k = 2; k <
size; k++)
432 if ((replacement_val = val (replacement = lits[k])) >= 0)
434 if (replacement_val >= 0) {
435 watcher (replacement).push_back (CheckerWatch (-
lit, c));
436 swap (lits[1], lits[k]);
438 }
else if (!other_val)
446 ws.resize (j - ws.begin ());
451bool Checker::check () {
455 unsigned previously_propagated = next_to_propagate;
456 for (
const auto &
lit : simplified)
458 bool res = !propagate ();
459 backtrack (previously_propagated);
463bool Checker::check_blocked () {
464 for (
const auto &
lit : unsimplified) {
467 vector<int> not_blocked;
468 for (
size_t i = 0; i < size_clauses; i++) {
469 for (CheckerClause *c = clauses[i], *next; c; c = next) {
473 for (
int *i = c->literals; i < c->literals + c->size; i++) {
476 LOG (c->literals, c->size,
"satisfied clause");
482 LOG (c->literals, c->size,
"clause");
487 not_blocked.push_back (first);
490 for (
const auto &
lit : not_blocked) {
493 bool blocked =
false;
494 for (
const auto &
lit : unsimplified) {
504void Checker::add_clause (
const char *
type) {
510 if (num_garbage > 0.5 * max ((
size_t) size_clauses, (
size_t) size_vars))
511 collect_garbage_clauses ();
514 for (
const auto &
lit : simplified) {
515 const signed char tmp = val (
lit);
526 if (simplified.empty ()) {
527 LOG (
"CHECKER added empty %s clause",
type);
531 LOG (
"CHECKER added and checked falsified %s clause",
type);
533 }
else if (unit != INT_MIN) {
534 LOG (
"CHECKER added and checked %s unit clause %d",
type, unit);
538 LOG (
"CHECKER inconsistent after propagating %s unit",
type);
550 LOG (c,
"CHECKER addition of original clause");
556 LOG (
"CHECKER ignoring satisfied original clause");
558 add_clause (
"original");
560 unsimplified.clear ();
569 LOG (c,
"CHECKER addition of derived clause");
575 LOG (
"CHECKER ignoring satisfied derived clause");
576 else if (!check () && !check_blocked ()) {
578 fputs (
"failed to check derived clause:\n", stderr);
579 for (
const auto &
lit : unsimplified)
580 fprintf (stderr,
"%d ",
lit);
584 add_clause (
"derived");
586 unsimplified.clear ();
592void Checker::delete_clause (int64_t
id,
bool,
const vector<int> &c) {
596 LOG (c,
"CHECKER checking deletion of clause");
599 unsimplified.clear ();
602 if (!tautological ()) {
616 fputs (
"deleted clause not in proof:\n", stderr);
617 for (
const auto &
lit : unsimplified)
618 fprintf (stderr,
"%d ",
lit);
624 unsimplified.clear ();
631 delete_clause (
id,
true, c);
638 for (uint64_t i = 0; i < size_clauses; i++)
640 for (
unsigned i = 0; i < c->size; i++)
641 if (abs (c->literals[i]) > max_var)
642 max_var = abs (c->literals[i]);
643 printf (
"p cnf %d %" PRIu64
"\n", max_var, num_clauses);
644 for (uint64_t i = 0; i < size_clauses; i++)
646 for (
unsigned i = 0; i < c->size; i++)
647 printf (
"%d ", c->literals[i]);
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
void add_assumption_clause(int64_t, const vector< int > &, const vector< int64_t > &) override
void connect_internal(Internal *i) override
void add_original_clause(int64_t, bool, const vector< int > &, bool=false) override
void add_derived_clause(int64_t, bool, const vector< int > &, const vector< int64_t > &) override
type
CUBE COVER and CUBE typedefs ///.
void fatal_message_start()
void clear_n(T *base, size_t n)
vector< CheckerWatch > CheckerWatcher
void erase_vector(std::vector< T > &v)
double percent(double a, double b)
bool operator()(int a, int b) const