ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
internal.c
Go to the documentation of this file.
1#include "allocate.h"
2#include "backtrack.h"
3#include "error.h"
4#include "import.h"
5#include "inline.h"
6#include "inlineframes.h"
7#include "print.h"
8#include "propsearch.h"
9#include "require.h"
10#include "resize.h"
11#include "resources.h"
12#include "search.h"
13
14#include <assert.h>
15#include <inttypes.h>
16#include <limits.h>
17#include <stdio.h>
18#include <stdlib.h>
19
21
26
28 kissat *solver = (kissat*)kissat_calloc (0, 1, sizeof *solver);
29#ifndef KISSAT_NOPTIONS
30 kissat_init_options (&solver->options);
31#else
33#endif
34#ifndef KISSAT_QUIET
35 kissat_init_profiles (&solver->profiles);
36#endif
37 START (total);
40 kissat_push_frame (solver, UINT_MAX);
41 solver->watching = true;
42 solver->conflict.size = 2;
43 solver->scinc = 1.0;
44 solver->first_reducible = INVALID_REF;
45 solver->last_irredundant = INVALID_REF;
47#ifndef KISSAT_NDEBUG
48 kissat_init_checker (solver);
49#endif
50 solver->prefix = kissat_strdup (solver, "c ");
51 return solver;
52}
53
54void kissat_set_prefix (kissat *solver, const char *prefix) {
55 kissat_freestr (solver, solver->prefix);
56 solver->prefix = kissat_strdup (solver, prefix);
57}
58
59#define DEALLOC_GENERIC(NAME, ELEMENTS_PER_BLOCK) \
60 do { \
61 const size_t block_size = ELEMENTS_PER_BLOCK * sizeof *solver->NAME; \
62 kissat_dealloc (solver, solver->NAME, solver->size, block_size); \
63 solver->NAME = 0; \
64 } while (0)
65
66#define DEALLOC_VARIABLE_INDEXED(NAME) DEALLOC_GENERIC (NAME, 1)
67
68#define DEALLOC_LITERAL_INDEXED(NAME) DEALLOC_GENERIC (NAME, 2)
69
70#define RELEASE_LITERAL_INDEXED_STACKS(NAME, ACCESS) \
71 do { \
72 for (all_stack (unsigned, IDX_RILIS, solver->active)) { \
73 const unsigned LIT_RILIS = LIT (IDX_RILIS); \
74 const unsigned NOT_LIT_RILIS = NOT (LIT_RILIS); \
75 RELEASE_STACK (ACCESS (LIT_RILIS)); \
76 RELEASE_STACK (ACCESS (NOT_LIT_RILIS)); \
77 } \
78 DEALLOC_LITERAL_INDEXED (NAME); \
79 } while (0)
80
84 kissat_release_heap (solver, &solver->schedule);
87
88 RELEASE_STACK (solver->export_);
89 RELEASE_STACK (solver->import);
90
94
98
99 RELEASE_STACK (solver->import);
100 RELEASE_STACK (solver->eliminated);
101 RELEASE_STACK (solver->extend);
102 RELEASE_STACK (solver->witness);
103 RELEASE_STACK (solver->etrail);
104
105 RELEASE_STACK (solver->delayed);
106
107 RELEASE_STACK (solver->clause);
108 RELEASE_STACK (solver->shadow);
109#if defined(LOGGING) || !defined(KISSAT_NDEBUG)
110 RELEASE_STACK (solver->resolvent);
111#endif
112
113 RELEASE_STACK (solver->arena);
114
115 RELEASE_STACK (solver->units);
116 RELEASE_STACK (solver->frames);
117 RELEASE_STACK (solver->sorter);
118
119 RELEASE_ARRAY (solver->trail, solver->size);
120
121 RELEASE_STACK (solver->analyzed);
122 RELEASE_STACK (solver->levels);
123 RELEASE_STACK (solver->minimize);
124 RELEASE_STACK (solver->poisoned);
125 RELEASE_STACK (solver->promote);
126 RELEASE_STACK (solver->removable);
127 RELEASE_STACK (solver->shrinkable);
128 RELEASE_STACK (solver->xorted[0]);
129 RELEASE_STACK (solver->xorted[1]);
130
131 RELEASE_STACK (solver->sweep_schedule);
132
133 RELEASE_STACK (solver->ranks);
134
135 RELEASE_STACK (solver->antecedents[0]);
136 RELEASE_STACK (solver->antecedents[1]);
137 RELEASE_STACK (solver->gates[0]);
138 RELEASE_STACK (solver->gates[1]);
139 RELEASE_STACK (solver->resolvents);
140
141#if !defined(KISSAT_NDEBUG) || !defined(KISSAT_NPROOFS)
142 RELEASE_STACK (solver->added);
143 RELEASE_STACK (solver->removed);
144#endif
145
146#if !defined(KISSAT_NDEBUG) || !defined(KISSAT_NPROOFS) || defined(LOGGING)
147 RELEASE_STACK (solver->original);
148#endif
149
150#ifndef KISSAT_QUIET
151 RELEASE_STACK (solver->profiles.stack);
152#endif
153
154 kissat_freestr (solver, solver->prefix);
155
156#ifndef KISSAT_NDEBUG
157 kissat_release_checker (solver);
158#endif
159#if !defined(KISSAT_NDEBUG) && defined(METRICS)
160 uint64_t leaked = solver->statistics_.allocated_current;
161 if (leaked)
162 if (!getenv ("LEAK"))
163 kissat_fatal ("internally leaking %" PRIu64 " bytes", leaked);
164#endif
165
166 kissat_free (0, solver, sizeof *solver);
167}
168
169void kissat_reserve (kissat *solver, int max_var) {
171 kissat_require (0 <= max_var, "negative maximum variable argument '%d'",
172 max_var);
174 "invalid maximum variable argument '%d'", max_var);
175 kissat_increase_size (solver, (unsigned) max_var);
176 if (!GET_OPTION (tumble)) {
177 for (int idx = 1; idx <= max_var; idx++)
178 (void) kissat_import_literal (solver, idx);
179 for (unsigned idx = 0; idx != (unsigned) max_var; idx++)
181 }
182}
183
184int kissat_get_option (kissat *solver, const char *name) {
186 kissat_require (name, "name zero pointer");
187#ifndef KISSAT_NOPTIONS
188 return kissat_options_get (&solver->options, name);
189#else
190 (void) solver;
191 return kissat_options_get (name);
192#endif
193}
194
195int kissat_set_option (kissat *solver, const char *name, int new_value) {
196#ifndef KISSAT_NOPTIONS
198 kissat_require (name, "name zero pointer");
199#ifndef KISSAT_NOPTIONS
200 return kissat_options_set (&solver->options, name, new_value);
201#else
202 return kissat_options_set (name, new_value);
203#endif
204#else
205 (void) solver, (void) new_value;
206 return kissat_options_get (name);
207#endif
208}
209
210void kissat_set_decision_limit (kissat *solver, unsigned limit) {
212 limits *limits = &solver->limits;
213 limited *limited = &solver->limited;
214 statistics *statistics = &solver->statistics_;
215 limited->decisions = true;
216 KISSAT_assert (UINT64_MAX - limit >= statistics->decisions);
217 limits->decisions = statistics->decisions + limit;
218 LOG ("set decision limit to %" PRIu64 " after %u decisions",
219 limits->decisions, limit);
220}
221
222void kissat_set_conflict_limit (kissat *solver, unsigned limit) {
224 limits *limits = &solver->limits;
225 limited *limited = &solver->limited;
226 statistics *statistics = &solver->statistics_;
227 limited->conflicts = true;
228 KISSAT_assert (UINT64_MAX - limit >= statistics->conflicts);
229 limits->conflicts = statistics->conflicts + limit;
230 LOG ("set conflict limit to %" PRIu64 " after %u conflicts",
231 limits->conflicts, limit);
232}
233
235#ifndef KISSAT_QUIET
237 const int verbosity = kissat_verbosity (solver);
238 if (verbosity < 0)
239 return;
240 if (GET_OPTION (profile)) {
241 kissat_section (solver, "profiling");
242 kissat_profiles_print (solver);
243 }
244 const bool complete = GET_OPTION (statistics);
245 kissat_section (solver, "statistics");
246 const bool verbose = (complete || verbosity > 0);
247 kissat_statistics_print (solver, verbose);
248#ifndef KISSAT_NPROOFS
249 if (solver->proof) {
250 kissat_section (solver, "proof");
251 kissat_print_proof_statistics (solver, verbose);
252 }
253#endif
254#ifndef KISSAT_NDEBUG
255 if (GET_OPTION (check) > 1) {
256 kissat_section (solver, "checker");
257 kissat_print_checker_statistics (solver, verbose);
258 }
259#endif
260 kissat_section (solver, "glue usage");
261 kissat_print_glue_usage (solver);
262 kissat_section (solver, "resources");
263 kissat_print_resources (solver);
264#endif
265 (void) solver;
266}
267
268void kissat_add (kissat *solver, int elit) {
270 kissat_require (!GET (searches), "incremental solving not supported");
271#if !defined(KISSAT_NDEBUG) || !defined(KISSAT_NPROOFS) || defined(LOGGING)
272 const int checking = kissat_checking (solver);
273 const bool logging = kissat_logging (solver);
274 const bool proving = kissat_proving (solver);
275#endif
276 if (elit) {
278#if !defined(KISSAT_NDEBUG) || !defined(KISSAT_NPROOFS) || defined(LOGGING)
279 if (checking || logging || proving)
280 PUSH_STACK (solver->original, elit);
281#endif
282 unsigned ilit = kissat_import_literal (solver, elit);
283
284 const mark mark = MARK (ilit);
285 if (!mark) {
286 const value value = kissat_fixed (solver, ilit);
287 if (value > 0) {
288 if (!solver->clause_satisfied) {
289 LOG ("adding root level satisfied literal %u(%d)@0=1", ilit,
290 elit);
291 solver->clause_satisfied = true;
292 }
293 } else if (value < 0) {
294 LOG ("adding root level falsified literal %u(%d)@0=-1", ilit, elit);
295 if (!solver->clause_shrink) {
296 solver->clause_shrink = true;
297 LOG ("thus original clause needs shrinking");
298 }
299 } else {
300 MARK (ilit) = 1;
301 MARK (NOT (ilit)) = -1;
302 KISSAT_assert (SIZE_STACK (solver->clause) < UINT_MAX);
303 PUSH_STACK (solver->clause, ilit);
304 }
305 } else if (mark < 0) {
306 KISSAT_assert (mark < 0);
307 if (!solver->clause_trivial) {
308 LOG ("adding dual literal %u(%d) and %u(%d)", NOT (ilit), -elit,
309 ilit, elit);
310 solver->clause_trivial = true;
311 }
312 } else {
313 KISSAT_assert (mark > 0);
314 LOG ("adding duplicated literal %u(%d)", ilit, elit);
315 if (!solver->clause_shrink) {
316 solver->clause_shrink = true;
317 LOG ("thus original clause needs shrinking");
318 }
319 }
320 } else {
321#if !defined(KISSAT_NDEBUG) || !defined(KISSAT_NPROOFS) || defined(LOGGING)
322 const size_t offset = solver->offset_of_last_original_clause;
323 size_t esize = SIZE_STACK (solver->original) - offset;
324 int *elits = BEGIN_STACK (solver->original) + offset;
325 KISSAT_assert (esize <= UINT_MAX);
326#endif
327 ADD_UNCHECKED_EXTERNAL (esize, elits);
328 const size_t isize = SIZE_STACK (solver->clause);
329 unsigned *ilits = BEGIN_STACK (solver->clause);
330 KISSAT_assert (isize < (unsigned) INT_MAX);
331
332 if (solver->inconsistent)
333 LOG ("inconsistent thus skipping original clause");
334 else if (solver->clause_satisfied)
335 LOG ("skipping satisfied original clause");
336 else if (solver->clause_trivial)
337 LOG ("skipping trivial original clause");
338 else {
339 kissat_activate_literals (solver, isize, ilits);
340
341 if (!isize) {
342 if (solver->clause_shrink)
343 LOG ("all original clause literals root level falsified");
344 else
345 LOG ("found empty original clause");
346
347 if (!solver->inconsistent) {
348 LOG ("thus solver becomes inconsistent");
349 solver->inconsistent = true;
352 }
353 } else if (isize == 1) {
354 unsigned unit = TOP_STACK (solver->clause);
355
356 if (solver->clause_shrink)
357 LOGUNARY (unit, "original clause shrinks to");
358 else
359 LOGUNARY (unit, "found original");
360
362
363 COVER (solver->level);
364 if (!solver->level)
366 } else {
368
369 const unsigned a = ilits[0];
370 const unsigned b = ilits[1];
371
372 const value u = VALUE (a);
373 const value v = VALUE (b);
374
375 const unsigned k = u ? LEVEL (a) : UINT_MAX;
376 const unsigned l = v ? LEVEL (b) : UINT_MAX;
377
378 bool assign = false;
379
380 if (!u && v < 0) {
381 LOG ("original clause immediately forcing");
382 assign = true;
383 } else if (u < 0 && k == l) {
384 LOG ("both watches falsified at level @%u", k);
385 KISSAT_assert (v < 0);
386 KISSAT_assert (k > 0);
388 } else if (u < 0) {
389 LOG ("watches falsified at levels @%u and @%u", k, l);
390 KISSAT_assert (v < 0);
391 KISSAT_assert (k > l);
392 KISSAT_assert (l > 0);
393 assign = true;
394 } else if (u > 0 && v < 0) {
395 LOG ("first watch satisfied at level @%u "
396 "second falsified at level @%u",
397 k, l);
398 KISSAT_assert (k <= l);
399 } else if (!u && v > 0) {
400 LOG ("first watch unassigned "
401 "second falsified at level @%u",
402 l);
403 assign = true;
404 } else {
405 KISSAT_assert (!u);
406 KISSAT_assert (!v);
407 }
408
409 if (assign) {
410 KISSAT_assert (solver->level > 0);
411
412 if (isize == 2) {
413 KISSAT_assert (res == INVALID_REF);
415 } else {
416 KISSAT_assert (res != INVALID_REF);
417 clause *c = kissat_dereference_clause (solver, res);
418 kissat_assign_reference (solver, a, res, c);
419 }
420 }
421 }
422 }
423
424#if !defined(KISSAT_NDEBUG) || !defined(KISSAT_NPROOFS)
425 if (solver->clause_satisfied || solver->clause_trivial) {
426#ifndef KISSAT_NDEBUG
427 if (checking > 1)
428 kissat_remove_checker_external (solver, esize, elits);
429#endif
430#ifndef KISSAT_NPROOFS
431 if (proving) {
432 if (esize == 1)
433 LOG ("skipping deleting unit from proof");
434 else
435 kissat_delete_external_from_proof (solver, esize, elits);
436 }
437#endif
438 } else if (!solver->inconsistent && solver->clause_shrink) {
439#ifndef KISSAT_NDEBUG
440 if (checking > 1) {
441 kissat_check_and_add_internal (solver, isize, ilits);
442 kissat_remove_checker_external (solver, esize, elits);
443 }
444#endif
445#ifndef KISSAT_NPROOFS
446 if (proving) {
447 kissat_add_lits_to_proof (solver, isize, ilits);
448 kissat_delete_external_from_proof (solver, esize, elits);
449 }
450#endif
451 }
452#endif
453
454#if !defined(KISSAT_NDEBUG) || !defined(KISSAT_NPROOFS) || defined(LOGGING)
455 if (checking) {
456 LOGINTS (esize, elits, "saved original");
457 PUSH_STACK (solver->original, 0);
458 solver->offset_of_last_original_clause =
459 SIZE_STACK (solver->original);
460 } else if (logging || proving) {
461 LOGINTS (esize, elits, "reset original");
462 CLEAR_STACK (solver->original);
463 solver->offset_of_last_original_clause = 0;
464 }
465#endif
466 for (all_stack (unsigned, lit, solver->clause))
467 MARK (lit) = MARK (NOT (lit)) = 0;
468
469 CLEAR_STACK (solver->clause);
470
471 solver->clause_satisfied = false;
472 solver->clause_trivial = false;
473 solver->clause_shrink = false;
474 }
475}
476
480 "incomplete clause (terminating zero not added)");
481 kissat_require (!GET (searches), "incremental solving not supported");
482 return kissat_search (solver);
483}
484
487 solver->termination.flagged = ~(unsigned) 0;
488 KISSAT_assert (solver->termination.flagged);
489}
490
492 int (*terminate) (void *)) {
493 solver->termination.terminate = 0;
494 solver->termination.state = state;
495 solver->termination.terminate = terminate;
496}
497
498int kissat_value (kissat *solver, int elit) {
501 const unsigned eidx = ABS (elit);
502 if (eidx >= SIZE_STACK (solver->import))
503 return 0;
504 const import *const import = &PEEK_STACK (solver->import, eidx);
505 if (!import->imported)
506 return 0;
507 value tmp;
508 if (import->eliminated) {
509 if (!solver->extended && !EMPTY_STACK (solver->extend))
511 const unsigned eliminated = import->lit;
512 tmp = PEEK_STACK (solver->eliminated, eliminated);
513 } else {
514 const unsigned ilit = import->lit;
515 tmp = VALUE (ilit);
516 }
517 if (!tmp)
518 return 0;
519 if (elit < 0)
520 tmp = -tmp;
521 return tmp < 0 ? -elit : elit;
522}
523
525 return solver->inconsistent;
526}
527
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
void * kissat_calloc(kissat *solver, size_t n, size_t size)
Definition allocate.c:97
void kissat_freestr(struct kissat *solver, char *str)
Definition allocate.c:75
void kissat_free(kissat *solver, void *ptr, size_t bytes)
Definition allocate.c:61
char * kissat_strdup(kissat *solver, const char *str)
Definition allocate.c:70
#define RELEASE_ARRAY(A, N)
Definition array.h:39
void kissat_original_unit(kissat *solver, unsigned lit)
Definition assign.c:24
void kissat_assign_binary(kissat *solver, unsigned lit, unsigned other)
Definition assign.c:34
void kissat_assign_reference(kissat *solver, unsigned lit, reference ref, clause *reason)
Definition assign.c:49
#define LEVEL(LIT)
Definition assign.h:34
void kissat_backtrack_without_updating_phases(kissat *solver, unsigned new_level)
Definition backtrack.c:74
#define BEGIN_STACK(S)
Definition stack.h:46
#define all_stack(T, E, S)
Definition stack.h:94
#define SIZE_STACK(S)
Definition stack.h:19
#define EMPTY_STACK(S)
Definition stack.h:18
#define RELEASE_STACK(S)
Definition stack.h:71
#define CLEAR_STACK(S)
Definition stack.h:50
#define PUSH_STACK(S, E)
Definition stack.h:39
#define PEEK_STACK(S, N)
Definition stack.h:29
#define TOP_STACK(S)
Definition stack.h:27
#define LOG(...)
ABC_NAMESPACE_IMPL_START typedef signed char value
#define CHECK_AND_ADD_EMPTY(...)
Definition check.h:146
#define ADD_UNCHECKED_EXTERNAL(...)
Definition check.h:134
reference kissat_new_original_clause(kissat *solver)
Definition clause.c:132
#define COVER(COND)
Definition cover.hpp:23
void kissat_fatal(const char *fmt,...)
Definition error.c:58
Cube * p
Definition exorList.c:222
void kissat_extend(kissat *solver)
Definition extend.c:46
void kissat_activate_literal(kissat *solver, unsigned lit)
Definition flags.c:52
void kissat_activate_literals(kissat *solver, unsigned size, unsigned *lits)
Definition flags.c:56
ABC_NAMESPACE_IMPL_START void kissat_release_heap(kissat *solver, heap *heap)
Definition heap.c:10
unsigned kissat_import_literal(kissat *solver, int elit)
Definition import.c:60
int kissat_value(kissat *solver, int elit)
Definition internal.c:498
void kissat_terminate(kissat *solver)
Definition internal.c:485
int kissat_solve(kissat *solver)
Definition internal.c:477
void kissat_set_conflict_limit(kissat *solver, unsigned limit)
Definition internal.c:222
ABC_NAMESPACE_IMPL_START void kissat_reset_last_learned(kissat *solver)
Definition internal.c:22
int kissat_get_option(kissat *solver, const char *name)
Definition internal.c:184
kissat * kissat_init(void)
Definition internal.c:27
void kissat_add(kissat *solver, int elit)
Definition internal.c:268
void kissat_set_terminate(kissat *solver, void *state, int(*terminate)(void *))
Definition internal.c:491
#define DEALLOC_LITERAL_INDEXED(NAME)
Definition internal.c:68
int kissat_set_option(kissat *solver, const char *name, int new_value)
Definition internal.c:195
void kissat_set_prefix(kissat *solver, const char *prefix)
Definition internal.c:54
#define DEALLOC_VARIABLE_INDEXED(NAME)
Definition internal.c:66
void kissat_release(kissat *solver)
Definition internal.c:81
void kissat_reserve(kissat *solver, int max_var)
Definition internal.c:169
void kissat_print_statistics(kissat *solver)
Definition internal.c:234
void kissat_set_decision_limit(kissat *solver, unsigned limit)
Definition internal.c:210
int kissat_is_inconsistent(kissat *solver)
Definition internal.c:524
#define really_all_last_learned(REF_PTR)
Definition internal.h:290
#define SCORES
Definition internal.h:262
#define KISSAT_assert(ignore)
Definition global.h:13
#define solver
Definition kitten.c:211
void kissat_init_options(void)
Definition kptions.c:178
int kissat_options_get(const char *name)
Definition kptions.c:180
#define LOGINTS(...)
Definition logging.h:394
#define LOGUNARY(...)
Definition logging.h:451
char * name
Definition main.h:24
#define GET_OPTION(N)
Definition options.h:295
void kissat_release_phases(kissat *solver)
Definition phases.c:43
#define kissat_section(...)
Definition print.h:49
#define START(P)
Definition profile.hpp:150
#define ADD_EMPTY_TO_PROOF(...)
Definition proof.h:135
clause * kissat_search_propagate(kissat *solver)
Definition propsearch.c:46
ABC_NAMESPACE_IMPL_START void kissat_init_queue(kissat *solver)
Definition queue.c:7
#define INVALID_REF
Definition reference.h:16
ABC_NAMESPACE_HEADER_START typedef unsigned reference
Definition reference.h:9
#define kissat_require(COND,...)
Definition require.h:7
#define kissat_require_valid_external_internal(LIT)
Definition require.h:22
#define kissat_require_initialized(SOLVER)
Definition require.h:19
void kissat_increase_size(kissat *solver, unsigned new_size)
Definition resize.c:52
int lit
Definition satVec.h:130
#define INTERNAL_MAX_LIT
Definition literal.h:14
#define LIT(IDX)
Definition literal.h:31
#define EXTERNAL_MAX_VAR
Definition literal.h:12
#define NOT(LIT)
Definition literal.h:33
int kissat_search(kissat *solver)
Definition search.c:181
#define GET(NAME)
Definition statistics.h:416
Definition flags.h:11
bool eliminated
Definition internal.h:52
bool imported
Definition internal.h:51
bool decisions
Definition kimits.h:61
bool conflicts
Definition kimits.h:60
uint64_t decisions
Definition kimits.h:28
uint64_t conflicts
Definition kimits.h:27
char * getenv()
#define ABS(a)
Definition util_old.h:250
#define MARK(LIT)
Definition value.h:12
signed char mark
Definition value.h:8
#define VALUE(LIT)
Definition value.h:10
void kissat_release_vectors(kissat *solver)
Definition vector.c:284
vector watches
Definition watch.h:49