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