1 /*
2 * This file is part of the Yices SMT Solver.
3 * Copyright (C) 2017 SRI International.
4 *
5 * Yices is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * Yices is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Yices. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /*
20 * STAND-ALONE SAT SOLVER
21 */
22
23 #ifndef __SAT_SOLVER_H
24 #define __SAT_SOLVER_H
25
26 #include <stdint.h>
27 #include <stdbool.h>
28 #include <stddef.h>
29 #include <assert.h>
30
31 #include "utils/bitvectors.h"
32 #include "utils/int_vectors.h"
33 #include "utils/stable_sort.h"
34 #include "utils/tag_map.h"
35
36
37 /************************************
38 * BOOLEAN VARIABLES AND LITERALS *
39 ***********************************/
40
41 /*
42 * Boolean variables: integers between 0 and nvars - 1
43 * Literals: integers between 0 and 2nvar - 1.
44 *
45 * For a variable x, the positive literal is 2x, the negative
46 * literal is 2x + 1.
47 *
48 * -1 is a special marker for both variables and literals
49 */
50 typedef int32_t bvar_t;
51 typedef int32_t literal_t;
52
53 enum {
54 null_bvar = -1,
55 null_literal = -1,
56 };
57
58
59 /*
60 * Maximal number of boolean variables
61 */
62 #define MAX_VARIABLES (UINT32_MAX >> 3)
63
64
65 /*
66 * Conversions from variables to literals
67 */
pos_lit(bvar_t x)68 static inline literal_t pos_lit(bvar_t x) {
69 return (x << 1);
70 }
71
neg_lit(bvar_t x)72 static inline literal_t neg_lit(bvar_t x) {
73 return (x << 1) + 1;
74 }
75
var_of(literal_t l)76 static inline bvar_t var_of(literal_t l) {
77 return l>>1;
78 }
79
80 // sign: 0 --> positive, 1 --> negative
sign_of(literal_t l)81 static inline int32_t sign_of(literal_t l) {
82 return l & 1;
83 }
84
85 // negation of literal l
not(literal_t l)86 static inline literal_t not(literal_t l) {
87 return l ^ 1;
88 }
89
90 // check whether l1 and l2 are opposite
opposite(literal_t l1,literal_t l2)91 static inline bool opposite(literal_t l1, literal_t l2) {
92 return (l1 ^ l2) == 1;
93 }
94
95 // true if l has positive polarity (i.e., l = pos_lit(x))
is_pos(literal_t l)96 static inline bool is_pos(literal_t l) {
97 return !(l & 1);
98 }
99
is_neg(literal_t l)100 static inline bool is_neg(literal_t l) {
101 return (l & 1);
102 }
103
104
105 /*
106 * Assignment values for a variable:
107 * - we use four values to encode the truth value of x
108 * when x is assigned and the preferred value when x is
109 * not assigned.
110 * - value[x] is interpreted as follows
111 * val_undef_false = 0b00 --> x not assigned, preferred value = false
112 * val_undef_true = 0b01 --> x not assigned, preferred value = true
113 * val_false = 0b10 --> x assigned false
114 * val_true = 0b11 --> x assigned true
115 *
116 * The preferred value is used when x is selected as a decision variable.
117 * Then we assign x to true or false depending on the preferred value.
118 * This is done by setting bit 1 in value[x].
119 */
120 typedef enum bval {
121 val_undef_false = 0,
122 val_undef_true = 1,
123 val_false = 2,
124 val_true = 3,
125 } bval_t;
126
127
128 // check whether val is undef_true or undef_false
is_unassigned_val(bval_t val)129 static inline bool is_unassigned_val(bval_t val) {
130 return (val & 0x2) == 0;
131 }
132
133 // check whether val is val_undef_true of val_true
true_preferred(bval_t val)134 static inline bool true_preferred(bval_t val) {
135 return (val & 0x1) != 0;
136 }
137
138
139
140 /*
141 * Problem status
142 */
143 typedef enum solver_status {
144 status_unsolved,
145 status_sat,
146 status_unsat,
147 } solver_status_t;
148
149
150 /*
151 * Codes returned by the propagation functions
152 */
153 enum {
154 no_conflict,
155 binary_conflict,
156 clause_conflict,
157 };
158
159
160
161 /***********
162 * CLAUSES *
163 **********/
164
165 /*
166 * Clauses structure
167 * - two pointers to form lists of clauses for the watched literals
168 * - a clause is an array of literals terminated by an end marker
169 * (a negative number).
170 * - the first two literals stored in cl[0] and cl[1]
171 * are the watched literals.
172 * Learned clauses have the same components as a clause
173 * and an activity, i.e., a float used by the clause-deletion
174 * heuristic. (Because of alignment and padding, this wastes 32bits
175 * on a 64bit machine....)
176 *
177 * Linked lists:
178 * - a link lnk is a pointer to a clause cl
179 * the low-order bits of lnk encode whether the next link is
180 * in cl->link[0] or cl->link[1]
181 * - this is compatible with the tagged pointers used as antecedents.
182 *
183 * SPECIAL CODING: to distinguish between learned clauses and problem
184 * clauses, the end marker is different.
185 * - for problem clauses, end_marker = -1
186 * - for learned clauses, end_marker = -2
187 *
188 * A solver stores a value for these two end_markers: it must
189 * always be equal to VAL_UNDEF.
190 *
191 * CLAUSE DELETION: to mark a clause for deletion, cl[0] and cl[1]
192 * are set to the same value.
193 */
194
195 enum {
196 end_clause = -1, // end of problem clause
197 end_learned = -2, // end of learned clause
198 };
199
200 typedef struct clause_s clause_t;
201
202 typedef uintptr_t link_t;
203
204 struct clause_s {
205 link_t link[2];
206 literal_t cl[0];
207 };
208
209
210 #define INSTRUMENT_CLAUSES 0
211
212 #if INSTRUMENT_CLAUSES
213
214 /*
215 * Instrumentation for learned clauses
216 * - creation = number of conflicts when the clause was created
217 * - deletion = number of conflicts when the clause is deleted
218 * - props = number of propagations involving that clause
219 * - last_prop = last time the clause caused a propagation
220 * - resos = number of times the clause is used in resolution
221 * - last_reso = last time the clause was involved in a resolution step
222 * - base_glue = glue score at creation
223 * - glue = last computed glue
224 * - min_glue = minimal of all glues so far
225 */
226 typedef struct lcstats_s {
227 uint32_t creation;
228 uint32_t deletion;
229 uint32_t props;
230 uint32_t last_prop;
231 uint32_t resos;
232 uint32_t last_reso;
233 uint32_t base_glue;
234 uint32_t glue;
235 uint32_t min_glue;
236 } lcstat_t;
237
238
239 typedef struct learned_clause_s {
240 lcstat_t stat;
241 float activity;
242 clause_t clause;
243 } learned_clause_t;
244
245
246 /*
247 * Statistics array for learned clauses
248 * - each element stores the stat record of a clause. It's set when
249 * the clause is deleted.
250 */
251 typedef struct learned_clauses_stats_s {
252 lcstat_t *data;
253 uint32_t nrecords;
254 uint32_t size;
255 FILE *file;
256 } learned_clauses_stats_t;
257
258
259 #else
260
261 /*
262 * No instrumentation of learned clauses
263 */
264 typedef struct learned_clause_s {
265 float activity;
266 clause_t clause;
267 } learned_clause_t;
268
269 #endif
270
271
272 /*
273 * Tagging/untagging of link pointers
274 */
275 #define LINK_TAG ((uintptr_t) 0x1)
276 #define NULL_LINK ((link_t) 0)
277
mk_link(clause_t * c,uint32_t i)278 static inline link_t mk_link(clause_t *c, uint32_t i) {
279 assert((i & ~LINK_TAG) == 0 && (((uintptr_t) c) & LINK_TAG) == 0);
280 return (link_t)(((uintptr_t) c) | ((uintptr_t) i));
281 }
282
clause_of(link_t lnk)283 static inline clause_t *clause_of(link_t lnk) {
284 return (clause_t *)(lnk & ~LINK_TAG);
285 }
286
idx_of(link_t lnk)287 static inline uint32_t idx_of(link_t lnk) {
288 return (uint32_t)(lnk & LINK_TAG);
289 }
290
next_of(link_t lnk)291 static inline link_t next_of(link_t lnk) {
292 return clause_of(lnk)->link[idx_of(lnk)];
293 }
294
295 /*
296 * return a new link lnk0 such that
297 * - clause_of(lnk0) = c
298 * - idx_of(lnk0) = i
299 * - next_of(lnk0) = lnk
300 */
cons(uint32_t i,clause_t * c,link_t lnk)301 static inline link_t cons(uint32_t i, clause_t *c, link_t lnk) {
302 assert(i <= 1);
303 c->link[i] = lnk;
304 return mk_link(c, i);
305 }
306
cdr_ptr(link_t lnk)307 static inline link_t *cdr_ptr(link_t lnk) {
308 return clause_of(lnk)->link + idx_of(lnk);
309 }
310
311
312
313
314
315
316 /**********
317 * SOLVER *
318 *********/
319
320 /*
321 * INTERNAL STRUCTURES
322 */
323
324 /*
325 * Vectors of clauses and literals
326 */
327 typedef struct clause_vector_s {
328 uint32_t capacity;
329 uint32_t size;
330 clause_t *data[0];
331 } clause_vector_t;
332
333 typedef struct literal_vector_s {
334 uint32_t capacity;
335 uint32_t size;
336 literal_t data[0];
337 } literal_vector_t;
338
339
340 /*
341 * Default initial sizes of vectors
342 */
343 #define DEF_CLAUSE_VECTOR_SIZE 100
344 #define DEF_LITERAL_VECTOR_SIZE 10
345 #define DEF_LITERAL_BUFFER_SIZE 100
346
347 #define MAX_LITERAL_VECTOR_SIZE (UINT32_MAX/4)
348
349
350 /*
351 * Assignment stack/propagation queue
352 * - an array of literals (the literals assigned to true)
353 * - two pointers: top of the stack, beginning of the propagation queue
354 * - for each decision level, an index into the stack points
355 * to the literal decided at that level (for backtracking)
356 */
357 typedef struct {
358 literal_t *lit;
359 uint32_t top;
360 uint32_t prop_ptr;
361 uint32_t *level_index;
362 uint32_t nlevels; // size of level_index array
363 } sol_stack_t;
364
365
366 /*
367 * Initial size of level_index
368 */
369 #define DEFAULT_NLEVELS 100
370
371
372 /*
373 * Heap and variable activities for variable selection heuristic
374 * - activity[x]: for every variable x between 0 and nvars - 1
375 * activity[-1] = DBL_MAX (higher than any activity)
376 * activity[-2] = -1.0 (lower than any variable activity)
377 * - heap_index[x]: for every variable x,
378 * heap_index[x] = i if x is in the heap and heap[i] = x
379 * or heap_index[x] = -1 if x is not in the heap
380 * - heap: array of nvars + 1 variables
381 * - heap_last: index of last element in the heap
382 * heap[0] = -1,
383 * for i=1 to heap_last, heap[i] = x for some variable x
384 * - size = number of variable (nvars)
385 * - vmax = variable index (last variable not in the heap)
386 * - act_inc: variable activity increment
387 * - inv_act_decay: inverse of variable activity decay (e.g., 1/0.95)
388 *
389 * The set of variables is split into two segments:
390 * - [0 ... vmax-1] = variables that are in the heap or have been in the heap
391 * - [vmax ... size-1] = variables that may not have been in the heap
392 *
393 * To pick a decision variable:
394 * - search for the most active unassigned variable in the heap
395 * - if the heap is empty or all its variables are already assigned,
396 * search for the first unassigned variables in [vmax ... size-1]
397 *
398 * Initially: we set vmax to 0 (nothing in the heap yet) so decision
399 * variables are picked in increasing order, starting from 0.
400 */
401 typedef struct var_heap_s {
402 double *activity;
403 int32_t *heap_index;
404 bvar_t *heap;
405 uint32_t heap_last;
406 uint32_t size;
407 uint32_t vmax;
408 double act_increment;
409 double inv_act_decay;
410 } var_heap_t;
411
412
413
414 /*
415 * Antecedent = either a clause or a literal or a generic explanation
416 * represented as tagged pointers. tag = two low-order bits
417 * - tag = 00: clause with implied literal as cl[0]
418 * - tag = 01: clause with implied literal as cl[1]
419 * - tag = 10: literal
420 * - tag = 11: generic explanation
421 *
422 * NOTE: generic explanation is not used for Boolean problems
423 */
424 typedef size_t antecedent_t;
425
426 enum {
427 clause0_tag = 0,
428 clause1_tag = 1,
429 literal_tag = 2,
430 generic_tag = 3,
431 };
432
antecedent_tag(antecedent_t a)433 static inline uint32_t antecedent_tag(antecedent_t a) {
434 return a & 0x3;
435 }
436
literal_antecedent(antecedent_t a)437 static inline literal_t literal_antecedent(antecedent_t a) {
438 return (literal_t) (a>>2);
439 }
440
clause_antecedent(antecedent_t a)441 static inline clause_t *clause_antecedent(antecedent_t a) {
442 return (clause_t *) (a & ~((uintptr_t) 0x3));
443 }
444
445 // clause index: 0 or 1, low order bit of a
clause_index(antecedent_t a)446 static inline uint32_t clause_index(antecedent_t a) {
447 return (uint32_t) (a & 0x1);
448 }
449
generic_antecedent(antecedent_t a)450 static inline void *generic_antecedent(antecedent_t a) {
451 return (void *) (a & ~((uintptr_t) 0x3));
452 }
453
mk_literal_antecedent(literal_t l)454 static inline antecedent_t mk_literal_antecedent(literal_t l) {
455 return (((uintptr_t) l) << 2) | literal_tag;
456 }
457
mk_clause0_antecedent(clause_t * cl)458 static inline antecedent_t mk_clause0_antecedent(clause_t *cl) {
459 assert((((uintptr_t) cl) & 0x3) == 0);
460 return ((uintptr_t) cl) | clause0_tag;
461 }
462
mk_clause1_antecedent(clause_t * cl)463 static inline antecedent_t mk_clause1_antecedent(clause_t *cl) {
464 assert((((uintptr_t) cl) & 0x3) == 0);
465 return ((uintptr_t) cl) | clause1_tag;
466 }
467
mk_clause_antecedent(clause_t * cl,int32_t index)468 static inline antecedent_t mk_clause_antecedent(clause_t *cl, int32_t index) {
469 assert((((uintptr_t) cl) & 0x3) == 0);
470 return ((uintptr_t) cl) | (index & 1);
471 }
472
mk_generic_antecedent(void * g)473 static inline antecedent_t mk_generic_antecedent(void *g) {
474 assert((((uintptr_t) g) & 0x3) == 0);
475 return ((uintptr_t) g) | generic_tag;
476 }
477
478
479
480 /*
481 * STATISTICS
482 */
483 typedef struct solver_stats_s {
484 uint32_t starts; // 1 + number of restarts
485 uint32_t simplify_calls; // number of calls to simplify_clause_database
486 uint32_t reduce_calls; // number of calls to reduce_learned_clause_set
487
488 uint64_t decisions; // number of decisions
489 uint64_t random_decisions; // number of random decisions
490 uint64_t propagations; // number of boolean propagations
491 uint64_t conflicts; // number of conflicts/backtracking
492
493 uint64_t prob_literals; // number of literals in problem clauses
494 uint64_t learned_literals; // number of literals in learned clauses
495 uint64_t aux_literals; // temporary counter for simplify_clause
496
497 uint64_t prob_clauses_deleted; // number of problem clauses deleted
498 uint64_t learned_clauses_deleted; // number of learned clauses deleted
499 uint64_t bin_clauses_deleted; // number of binary clauses deleted
500
501 uint64_t literals_before_simpl;
502 uint64_t subsumed_literals;
503 } solver_stats_t;
504
505
506 /*
507 * Solver state
508 * - global flags and counters
509 * - clause data base divided into:
510 * - vector of problem clauses
511 * - vector of learned clauses
512 * unit and binary clauses are stored implicitly.
513 * - propagation structures: for every literal l
514 * bin[l] = literal vector for binary clauses
515 * watch[l] = list of clauses where l is a watched literal
516 * (i.e., clauses where l occurs in position 0 or 1)
517 *
518 * - for every variable x between 0 and nb_vars - 1
519 * - antecedent[x]: antecedent type and value
520 * - level[x]: decision level (only meaningful if x is assigned)
521 * - mark[x]: 1 bit used in UIP computation
522 *
523 * - for every literal l between 0 and nb_lits - 1
524 * - value[l] = current assignment
525 * - value[-2] = value[-1] = val_undef_false
526 * - a heap for the decision heuristic
527 *
528 * - an assignment stack
529 *
530 * - other arrays for constructing and simplifying learned clauses
531 */
532 typedef struct sat_solver_s {
533 uint32_t status; // UNSOLVED, SAT, OR UNSAT
534
535 uint32_t nb_vars; // Number of variables
536 uint32_t nb_lits; // Number of literals = twice the number of variables
537 uint32_t vsize; // Size of the variable arrays (>= nb_vars)
538 uint32_t lsize; // size of the literal arrays (>= nb_lits)
539
540 uint32_t nb_clauses; // Number of clauses with at least 3 literals
541 uint32_t nb_unit_clauses; // Number of unit clauses
542 uint32_t nb_bin_clauses; // Number of binary clauses
543
544 /* Activity increments and decays for learned clauses */
545 float cla_inc; // Clause activity increment
546 float inv_cla_decay; // Inverse of clause decay (e.g., 1/0.999)
547
548 /* Current decision level */
549 uint32_t decision_level;
550 uint32_t backtrack_level;
551
552 /* Simplify DB heuristic */
553 uint32_t simplify_bottom; // stack top pointer after last simplify_clause_database
554 uint64_t simplify_props; // value of propagation counter at that point
555 uint64_t simplify_threshold; // number of propagations before simplify is enabled again
556
557 /* Reduce DB heuristic */
558 uint32_t reduce_threshold; // number of learned clauses before reduce is called
559
560 /* Statistics */
561 solver_stats_t stats;
562
563 /* Clause database */
564 clause_t **problem_clauses;
565 clause_t **learned_clauses;
566
567 /* Variable-indexed arrays */
568 antecedent_t *antecedent;
569 uint32_t *level;
570 byte_t *mark; // bitvector
571
572 /* Literal-indexed arrays */
573 uint8_t *value;
574 literal_t **bin; // array of literal vectors
575 link_t *watch; // array of watch lists
576
577 /* Heap */
578 var_heap_t heap;
579
580 /* Stack */
581 sol_stack_t stack;
582
583 /* Auxiliary vectors for conflict analysis */
584 ivector_t buffer;
585 ivector_t buffer2;
586
587 /* Conflict clauses stored in short_buffer or via conflict pointer */
588 literal_t short_buffer[4];
589 literal_t *conflict;
590 clause_t *false_clause;
591
592 /* Sorter: used in deletion of learned clauses */
593 stable_sorter_t sorter;
594 } sat_solver_t;
595
596
597
598
599 /*
600 * Access to truth assignment
601 */
lit_val(sat_solver_t * solver,literal_t l)602 static inline bval_t lit_val(sat_solver_t *solver, literal_t l) {
603 assert(-2 <= l && l < (int32_t) solver->nb_lits);
604 return solver->value[l];
605 }
606
lit_is_unassigned(sat_solver_t * solver,literal_t l)607 static inline bool lit_is_unassigned(sat_solver_t *solver, literal_t l) {
608 return is_unassigned_val(lit_val(solver, l));
609 }
610
lit_is_assigned(sat_solver_t * solver,literal_t l)611 static inline bool lit_is_assigned(sat_solver_t *solver, literal_t l) {
612 return ! lit_is_unassigned(solver, l);
613 }
614
var_is_assigned(sat_solver_t * solver,bvar_t x)615 static inline bool var_is_assigned(sat_solver_t *solver, bvar_t x) {
616 return lit_is_assigned(solver, pos_lit(x));
617 }
618
var_is_unassigned(sat_solver_t * solver,bvar_t x)619 static inline bool var_is_unassigned(sat_solver_t *solver, bvar_t x) {
620 return !var_is_assigned(solver, x);
621 }
622
623
lit_prefers_true(sat_solver_t * solver,literal_t l)624 static inline bool lit_prefers_true(sat_solver_t *solver, literal_t l) {
625 return true_preferred(lit_val(solver, l));
626 }
627
628
629 /********************
630 * MAIN FUNCTIONS *
631 *******************/
632
633 /*
634 * Solver initialization
635 * - size = initial size of the variable arrays
636 */
637 extern void init_sat_solver(sat_solver_t *solver, uint32_t size);
638
639 /*
640 * Set the prng seed
641 */
642 extern void sat_solver_set_seed(sat_solver_t *solver, uint32_t seed);
643
644
645 /*
646 * Delete solver
647 */
648 extern void delete_sat_solver(sat_solver_t *solver);
649
650 /*
651 * Add n fresh variables
652 */
653 extern void sat_solver_add_vars(sat_solver_t *solver, uint32_t n);
654
655 /*
656 * Allocate a fresh boolean variable and return its index
657 */
658 extern bvar_t sat_solver_new_var(sat_solver_t *solver);
659
660 /*
661 * Addition of simplified clause
662 * - each clause is an array of literals (integers between 0 and 2nvars - 1)
663 * that does not contain twice the same literals or complementary literals
664 */
665 extern void sat_solver_add_empty_clause(sat_solver_t *solver);
666 extern void sat_solver_add_unit_clause(sat_solver_t *solver, literal_t l);
667 extern void sat_solver_add_binary_clause(sat_solver_t *solver, literal_t l0, literal_t l1);
668 extern void sat_solver_add_ternary_clause(sat_solver_t *solver, literal_t l0, literal_t l1,
669 literal_t l2);
670
671 // clause l[0] ... l[n-1]
672 extern void sat_solver_add_clause(sat_solver_t *solver, uint32_t n, literal_t *l);
673
674
675 /*
676 * Simplify then add a clause: remove duplicate literals, and already
677 * assigned literals, and simplify
678 */
679 extern void sat_solver_simplify_and_add_clause(sat_solver_t *solver, uint32_t n, literal_t *l);
680
681
682
683 /*
684 * Bounded search: search until either unsat or sat is determined, or until
685 * the number of conflicts generated reaches conflict_bound.
686 * Return status_unsat, status_sat if the problem is solved.
687 * Return status_unknown if the conflict bound is reached.
688 *
689 * The return value is also kept as solver->status.
690 */
691 extern solver_status_t search(sat_solver_t *solver, uint32_t conflict_bound);
692
693
694 /*
695 * Solve the problem: repeatedly calls search until it returns sat or unsat.
696 * - initial conflict_bound = 100.
697 * - initial del_threshold = number of clauses / 3.
698 * - at every iteration, conflict_bound is increased by 50% and del_threshold by 10%
699 * - if verbose is true, print statistics on stderr during the search
700 */
701 extern solver_status_t solve(sat_solver_t *solver, bool verbose);
702
703
704 /*
705 * Access to solver fields
706 */
solver_status(sat_solver_t * solver)707 static inline solver_status_t solver_status(sat_solver_t *solver) {
708 return solver->status;
709 }
710
solver_nvars(sat_solver_t * solver)711 static inline uint32_t solver_nvars(sat_solver_t *solver) {
712 return solver->nb_vars;
713 }
714
solver_nliterals(sat_solver_t * solver)715 static inline uint32_t solver_nliterals(sat_solver_t *solver) {
716 return solver->nb_lits;
717 }
718
solver_statistics(sat_solver_t * solver)719 static inline solver_stats_t * solver_statistics(sat_solver_t *solver) {
720 return &solver->stats;
721 }
722
723
724 /*
725 * Read variable/literal assignments
726 */
get_literal_assignment(sat_solver_t * solver,literal_t l)727 static inline bval_t get_literal_assignment(sat_solver_t *solver, literal_t l) {
728 assert(0 <= l && l < solver->nb_lits);
729 return lit_val(solver, l);
730 }
731
get_variable_assignment(sat_solver_t * solver,bvar_t x)732 static inline bval_t get_variable_assignment(sat_solver_t *solver, bvar_t x) {
733 assert(0 <= x && x < solver->nb_vars);
734 return lit_val(solver, pos_lit(x));
735 }
736
737 /*
738 * Copy the full variable assignment in array val.
739 * - val must have size >= solver->nb_vars
740 */
741 extern void get_allvars_assignment(sat_solver_t *solver, bval_t *val);
742
743
744 /*
745 * Copy all the literals assigned to true in array a
746 * - return the number of literals copied.
747 * - a must be have size >= solver->nb_vars
748 */
749 extern uint32_t get_true_literals(sat_solver_t *solver, literal_t *a);
750
751
752 #if INSTRUMENT_CLAUSES
753
754 /*
755 * Statistics records:
756 * - allocate the statistics data structure
757 * - f must be open and writeable. It will be use to
758 * store the statistics data.
759 */
760 extern void init_learned_clauses_stats(FILE *f);
761
762
763 /*
764 * Save all statistics into the statistics file
765 */
766 extern void flush_learned_clauses_stats(void);
767
768 #endif
769
770
771 #endif /* __SAT_SOLVER_H */
772