ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
cadical_idruptracer.cpp
Go to the documentation of this file.
1#include "global.h"
2
3#include "internal.hpp"
4
6
7namespace CaDiCaL {
8
9/*------------------------------------------------------------------------*/
10
12 : internal (i), file (f), binary (b), num_clauses (0), size_clauses (0),
13 clauses (0), last_hash (0), last_id (0), last_clause (0)
14#ifndef CADICAL_QUIET
15 ,
16 added (0), deleted (0)
17#endif
18{
19 (void) internal;
20
21 // Initialize random number table for hash function.
22 //
23 Random random (42);
24 for (unsigned n = 0; n < num_nonces; n++) {
25 uint64_t nonce = random.next ();
26 if (!(nonce & 1))
27 nonce++;
28 CADICAL_assert (nonce), CADICAL_assert (nonce & 1);
29 nonces[n] = nonce;
30 }
31#ifndef CADICAL_NDEBUG
32 binary = b;
33#else
34 (void) b;
35#endif
36 piping = file->piping ();
37}
38
40 internal = i;
41 file->connect_internal (internal);
42 LOG ("IDRUP TRACER connected to internal");
43}
44
46 LOG ("IDRUP TRACER delete");
47 delete file;
48 for (size_t i = 0; i < size_clauses; i++)
49 for (IdrupClause *c = clauses[i], *next; c; c = next)
50 next = c->next, delete_clause (c);
51 delete[] clauses;
52}
53
54/*------------------------------------------------------------------------*/
55
56void IdrupTracer::enlarge_clauses () {
57 CADICAL_assert (num_clauses == size_clauses);
58 const uint64_t new_size_clauses = size_clauses ? 2 * size_clauses : 1;
59 LOG ("IDRUP Tracer enlarging clauses of tracer from %" PRIu64
60 " to %" PRIu64,
61 (uint64_t) size_clauses, (uint64_t) new_size_clauses);
62 IdrupClause **new_clauses;
63 new_clauses = new IdrupClause *[new_size_clauses];
64 clear_n (new_clauses, new_size_clauses);
65 for (uint64_t i = 0; i < size_clauses; i++) {
66 for (IdrupClause *c = clauses[i], *next; c; c = next) {
67 next = c->next;
68 const uint64_t h = reduce_hash (c->hash, new_size_clauses);
69 c->next = new_clauses[h];
70 new_clauses[h] = c;
71 }
72 }
73 delete[] clauses;
74 clauses = new_clauses;
75 size_clauses = new_size_clauses;
76}
77
78IdrupClause *IdrupTracer::new_clause () {
79 const size_t size = imported_clause.size ();
80 CADICAL_assert (size <= UINT_MAX);
81 const int off = size ? -1 : 0;
82 const size_t bytes = sizeof (IdrupClause) + (size - off) * sizeof (int);
83 IdrupClause *res = (IdrupClause *) new char[bytes];
84 res->next = 0;
85 res->hash = last_hash;
86 res->id = last_id;
87 res->size = size;
88 int *literals = res->literals, *p = literals;
89 for (const auto &lit : imported_clause) {
90 *p++ = lit;
91 }
92 last_clause = res;
93 num_clauses++;
94 return res;
95}
96
97void IdrupTracer::delete_clause (IdrupClause *c) {
99 num_clauses--;
100 delete[] (char *) c;
101}
102
103uint64_t IdrupTracer::reduce_hash (uint64_t hash, uint64_t size) {
104 CADICAL_assert (size > 0);
105 unsigned shift = 32;
106 uint64_t res = hash;
107 while ((((uint64_t) 1) << shift) > size) {
108 res ^= res >> shift;
109 shift >>= 1;
110 }
111 res &= size - 1;
112 CADICAL_assert (res < size);
113 return res;
114}
115
116uint64_t IdrupTracer::compute_hash (const int64_t id) {
117 CADICAL_assert (id > 0);
118 unsigned j = id % num_nonces;
119 uint64_t tmp = nonces[j] * (uint64_t) id;
120 return last_hash = tmp;
121}
122
123bool IdrupTracer::find_and_delete (const int64_t id) {
124 if (!num_clauses)
125 return false;
126 IdrupClause **res = 0, *c;
127 const uint64_t hash = compute_hash (id);
128 const uint64_t h = reduce_hash (hash, size_clauses);
129 for (res = clauses + h; (c = *res); res = &c->next) {
130 if (c->hash == hash && c->id == id) {
131 break;
132 }
133 if (!c->next)
134 return false;
135 }
136 if (!c)
137 return false;
138 CADICAL_assert (c && res);
139 *res = c->next;
140 int *begin = c->literals;
141 for (size_t i = 0; i < c->size; i++) {
142 imported_clause.push_back (begin[i]);
143 }
144 delete_clause (c);
145 return true;
146}
147
148void IdrupTracer::insert () {
149 if (num_clauses == size_clauses)
150 enlarge_clauses ();
151 const uint64_t h = reduce_hash (compute_hash (last_id), size_clauses);
152 IdrupClause *c = new_clause ();
153 c->next = clauses[h];
154 clauses[h] = c;
155}
156
157/*------------------------------------------------------------------------*/
158
159inline void IdrupTracer::flush_if_piping () {
160 if (piping)
161 file->flush ();
162}
163
164inline void IdrupTracer::put_binary_zero () {
165 CADICAL_assert (binary);
166 CADICAL_assert (file);
167 file->put ((unsigned char) 0);
168}
169
170inline void IdrupTracer::put_binary_lit (int lit) {
171 CADICAL_assert (binary);
172 CADICAL_assert (file);
173 CADICAL_assert (lit != INT_MIN);
174 unsigned x = 2 * abs (lit) + (lit < 0);
175 unsigned char ch;
176 while (x & ~0x7f) {
177 ch = (x & 0x7f) | 0x80;
178 file->put (ch);
179 x >>= 7;
180 }
181 ch = x;
182 file->put (ch);
183}
184
185inline void IdrupTracer::put_binary_id (int64_t id, bool can_be_negative) {
186 CADICAL_assert (binary);
187 CADICAL_assert (file);
188 uint64_t x = abs (id);
189 if (can_be_negative) {
190 x = 2 * x + (id < 0);
191 }
192 unsigned char ch;
193 while (x & ~0x7f) {
194 ch = (x & 0x7f) | 0x80;
195 file->put (ch);
196 x >>= 7;
197 }
198 ch = x;
199 file->put (ch);
200}
201
202/*------------------------------------------------------------------------*/
203
204void IdrupTracer::idrup_add_restored_clause (const vector<int> &clause) {
205 if (binary)
206 file->put ('r');
207 else
208 file->put ("r ");
209 for (const auto &external_lit : clause)
210 if (binary)
211 put_binary_lit (external_lit);
212 else
213 file->put (external_lit), file->put (' ');
214 if (binary)
215 put_binary_zero ();
216 else
217 file->put ("0\n");
218 // flush_if_piping ();
219}
220
221void IdrupTracer::idrup_add_derived_clause (const vector<int> &clause) {
222 if (binary)
223 file->put ('l');
224 else
225 file->put ("l ");
226 for (const auto &external_lit : clause)
227 if (binary)
228 put_binary_lit (external_lit);
229 else
230 file->put (external_lit), file->put (' ');
231 if (binary)
232 put_binary_zero ();
233 else
234 file->put ("0\n");
235 // flush_if_piping ();
236}
237
238void IdrupTracer::idrup_add_original_clause (const vector<int> &clause) {
239 if (binary)
240 file->put ('i');
241 else
242 file->put ("i ");
243 for (const auto &external_lit : clause)
244 if (binary)
245 put_binary_lit (external_lit);
246 else
247 file->put (external_lit), file->put (' ');
248 if (binary)
249 put_binary_zero ();
250 else
251 file->put ("0\n");
252 // flush_if_piping ();
253}
254
255void IdrupTracer::idrup_delete_clause (int64_t id,
256 const vector<int> &clause) {
257 if (find_and_delete (id)) {
258 CADICAL_assert (imported_clause.empty ());
259 if (binary)
260 file->put ('w');
261 else
262 file->put ("w ");
263#ifndef CADICAL_QUIET
264 weakened++;
265#endif
266 } else {
267 if (binary)
268 file->put ('d');
269 else
270 file->put ("d ");
271#ifndef CADICAL_QUIET
272 deleted++;
273#endif
274 }
275 for (const auto &external_lit : clause)
276 if (binary)
277 put_binary_lit (external_lit);
278 else
279 file->put (external_lit), file->put (' ');
280 if (binary)
281 put_binary_zero ();
282 else
283 file->put ("0\n");
284 // flush_if_piping ();
285}
286
287void IdrupTracer::idrup_conclude_and_delete (
288 const vector<int64_t> &conclusion) {
289 uint64_t size = conclusion.size ();
290 if (size > 1) {
291 if (binary) {
292 file->put ('U');
293 put_binary_id (size);
294 } else {
295 file->put ("U ");
296 file->put (size), file->put ("\n");
297 }
298 }
299 for (auto &id : conclusion) {
300 if (binary)
301 file->put ('u');
302 else
303 file->put ("u ");
304 (void) find_and_delete (id);
305 for (const auto &external_lit : imported_clause) {
306 // flip sign...
307 const auto not_elit = -external_lit;
308 if (binary)
309 put_binary_lit (not_elit);
310 else
311 file->put (not_elit), file->put (' ');
312 }
313 if (binary)
314 put_binary_zero ();
315 else
316 file->put ("0\n");
317 imported_clause.clear ();
318 }
319 flush_if_piping ();
320}
321
322void IdrupTracer::idrup_report_status (int status) {
323 if (binary)
324 file->put ('s');
325 else
326 file->put ("s ");
327 if (status == SATISFIABLE)
328 file->put ("SATISFIABLE");
329 else if (status == UNSATISFIABLE)
330 file->put ("UNSATISFIABLE");
331 else
332 file->put ("UNKNOWN");
333 if (!binary)
334 file->put ("\n");
335 flush_if_piping ();
336}
337
338void IdrupTracer::idrup_conclude_sat (const vector<int> &model) {
339 if (binary)
340 file->put ('m');
341 else
342 file->put ("m ");
343 for (auto &lit : model) {
344 if (binary)
345 put_binary_lit (lit);
346 else
347 file->put (lit), file->put (' ');
348 }
349 if (binary)
350 put_binary_zero ();
351 else
352 file->put ("0\n");
353 flush_if_piping ();
354}
355
356void IdrupTracer::idrup_conclude_unknown (const vector<int> &trail) {
357 if (binary)
358 file->put ('e');
359 else
360 file->put ("e ");
361 for (auto &lit : trail) {
362 if (binary)
363 put_binary_lit (lit);
364 else
365 file->put (lit), file->put (' ');
366 }
367 if (binary)
368 put_binary_zero ();
369 else
370 file->put ("0\n");
371 flush_if_piping ();
372}
373
374void IdrupTracer::idrup_solve_query () {
375 if (binary)
376 file->put ('q');
377 else
378 file->put ("q ");
379 for (auto &lit : assumptions) {
380 if (binary)
381 put_binary_lit (lit);
382 else
383 file->put (lit), file->put (' ');
384 }
385 if (binary)
386 put_binary_zero ();
387 else
388 file->put ("0\n");
389 flush_if_piping ();
390}
391
392/*------------------------------------------------------------------------*/
393
395 const vector<int> &clause,
396 const vector<int64_t> &) {
397 if (file->closed ())
398 return;
399 CADICAL_assert (imported_clause.empty ());
400 LOG (clause, "IDRUP TRACER tracing addition of derived clause");
401 idrup_add_derived_clause (clause);
402#ifndef CADICAL_QUIET
403 added++;
404#endif
405}
406
408 const vector<int> &clause,
409 const vector<int64_t> &) {
410 if (file->closed ())
411 return;
412 CADICAL_assert (imported_clause.empty ());
413 LOG (clause, "IDRUP TRACER tracing addition of assumption clause");
414 for (auto &lit : clause)
415 imported_clause.push_back (lit);
416 last_id = id;
417 insert ();
418 imported_clause.clear ();
419}
420
421void IdrupTracer::delete_clause (int64_t id, bool,
422 const vector<int> &clause) {
423 if (file->closed ())
424 return;
425 CADICAL_assert (imported_clause.empty ());
426 LOG ("IDRUP TRACER tracing deletion of clause[%" PRId64 "]", id);
427 idrup_delete_clause (id, clause);
428}
429
430void IdrupTracer::weaken_minus (int64_t id, const vector<int> &) {
431 if (file->closed ())
432 return;
433 CADICAL_assert (imported_clause.empty ());
434 LOG ("IDRUP TRACER tracing weaken minus of clause[%" PRId64 "]", id);
435 last_id = id;
436 insert ();
437#ifndef CADICAL_QUIET
438 weakened++;
439#endif
440}
441
443 const vector<int64_t> &conclusion) {
444 if (file->closed ())
445 return;
446 CADICAL_assert (imported_clause.empty ());
447 LOG (conclusion, "IDRUP TRACER tracing conclusion of clause(s)");
448 idrup_conclude_and_delete (conclusion);
449}
450
451void IdrupTracer::add_original_clause (int64_t id, bool,
452 const vector<int> &clause,
453 bool restored) {
454 if (file->closed ())
455 return;
456 if (!restored) {
457 LOG (clause, "IDRUP TRACER tracing addition of original clause");
458#ifndef CADICAL_QUIET
459 original++;
460#endif
461 return idrup_add_original_clause (clause);
462 }
463 CADICAL_assert (restored);
464 if (find_and_delete (id)) {
465 LOG (clause,
466 "IDRUP TRACER the clause was not yet weakened, so no restore");
467 return;
468 }
469 LOG (clause, "IDRUP TRACER tracing addition of restored clause");
470 idrup_add_restored_clause (clause);
471#ifndef CADICAL_QUIET
472 restore++;
473#endif
474}
475
476void IdrupTracer::report_status (int status, int64_t) {
477 if (file->closed ())
478 return;
479 LOG ("IDRUP TRACER tracing report of status %d", status);
480 idrup_report_status (status);
481}
482
484 if (file->closed ())
485 return;
486 LOG (model, "IDRUP TRACER tracing conclusion of model");
487 idrup_conclude_sat (model);
488}
489
491 if (file->closed ())
492 return;
493 LOG (trail, "IDRUP TRACER tracing conclusion of unknown state");
494 idrup_conclude_unknown (trail);
495}
496
498 if (file->closed ())
499 return;
500 LOG (assumptions, "IDRUP TRACER tracing solve query with assumptions");
501 idrup_solve_query ();
502#ifndef CADICAL_QUIET
503 solved++;
504#endif
505}
506
508 LOG ("IDRUP TRACER tracing addition of assumption %d", lit);
509 assumptions.push_back (lit);
510}
511
513 LOG (assumptions, "IDRUP TRACER tracing reset of assumptions");
514 assumptions.clear ();
515}
516
517/*------------------------------------------------------------------------*/
518
519bool IdrupTracer::closed () { return file->closed (); }
520
521#ifndef CADICAL_QUIET
522
523void IdrupTracer::print_statistics () {
524 // TODO complete this.
525 uint64_t bytes = file->bytes ();
526 uint64_t total = added + deleted + weakened + restore + original;
527 MSG ("LIDRUP %" PRId64 " original clauses %.2f%%", original,
528 percent (original, total));
529 MSG ("LIDRUP %" PRId64 " learned clauses %.2f%%", added,
530 percent (added, total));
531 MSG ("LIDRUP %" PRId64 " deleted clauses %.2f%%", deleted,
532 percent (deleted, total));
533 MSG ("LIDRUP %" PRId64 " weakened clauses %.2f%%", weakened,
534 percent (weakened, total));
535 MSG ("LIDRUP %" PRId64 " restored clauses %.2f%%", restore,
536 percent (restore, total));
537 MSG ("LIDRUP %" PRId64 " queries %.2f", solved, relative (solved, total));
538 MSG ("IDRUP %" PRId64 " bytes (%.2f MB)", bytes,
539 bytes / (double) (1 << 20));
540}
541
542#endif
543
544void IdrupTracer::close (bool print) {
546 file->close ();
547#ifndef CADICAL_QUIET
548 if (print) {
549 MSG ("IDRUP proof file '%s' closed", file->name ());
550 print_statistics ();
551 }
552#else
553 (void) print;
554#endif
555}
556
557void IdrupTracer::flush (bool print) {
559 file->flush ();
560#ifndef CADICAL_QUIET
561 if (print) {
562 MSG ("IDRUP proof file '%s' flushed", file->name ());
563 print_statistics ();
564 }
565#else
566 (void) print;
567#endif
568}
569
570} // namespace CaDiCaL
571
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
Definition global.h:14
#define CADICAL_QUIET
Definition global.h:8
#define LOG(...)
void conclude_unknown(const vector< int > &) override
void flush(bool) override
void connect_internal(Internal *i) 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 reset_assumptions() override
void report_status(int, int64_t) override
void conclude_sat(const vector< int > &) override
void add_assumption(int) override
IdrupTracer(Internal *, File *file, bool)
void weaken_minus(int64_t, const vector< int > &) override
void conclude_unsat(ConclusionType, const vector< int64_t > &) override
void close(bool) override
void add_original_clause(int64_t, bool, const vector< int > &, bool=false) override
Cube * p
Definition exorList.c:222
#define MSG(...)
Definition message.hpp:49
double relative(double a, double b)
Definition util.hpp:20
ConclusionType
Definition tracer.hpp:15
@ UNSATISFIABLE
Definition cadical.hpp:30
@ SATISFIABLE
Definition cadical.hpp:29
void clear_n(T *base, size_t n)
Definition util.hpp:149
double percent(double a, double b)
Definition util.hpp:21
unsigned long long size
Definition giaNewBdd.h:39
struct clause_t clause
STRUCTURE DEFINITIONS ///.
Definition satClause.h:48
int lit
Definition satVec.h:130
Definition file.h:23
uint64_t bytes
Definition file.h:29
unsigned size
Definition vector.h:35
long random()