1. kissat结构体的基本数据成员回顾:

//最常用的数据成员访问代码:
  watches *const all_watches = solver->watches;
  ward *const arena = BEGIN_STACK (solver->arena);
  assigned *const assigned = solver->assigned;
  value *const values = solver->values;

    unsigned_array *trail = &solver->trail;

 

(1)子对象对应的相关类型

 
 1 #include "arena.h"  //包含#include "reference.h"  #include "stack.h"  #include "utilities.h"
 2 #include "array.h"
 3 #include "assign.h" //包含 #include "reference.h"
 4 #include "averages.h"
 5 #include "check.h"
 6 #include "classify.h"
 7 #include "clause.h"
 8 #include "cover.h"
 9 #include "extend.h"
10 #include "flags.h"
11 #include "format.h"
12 #include "frames.h"
13 #include "heap.h"
14 #include "kimits.h"
15 #include "kissat.h"
16 #include "literal.h"
17 #include "mode.h"
18 #include "options.h"
19 #include "phases.h"
20 #include "profile.h"
21 #include "proof.h"
22 #include "queue.h"
23 #include "random.h"
24 #include "reluctant.h"
25 #include "rephase.h"
26 #include "smooth.h"
27 #include "stack.h"
28 #include "statistics.h"
29 #include "value.h"
30 #include "vector.h"
31 #include "watch.h"
32 
33 typedef struct datarank datarank;
34 
35 struct datarank {
36   unsigned data;
37   unsigned rank;
38 };
39 
40 typedef struct import import;
41 
42 struct import {
43   unsigned lit;
44   bool extension;
45   bool imported;
46   bool eliminated;
47 };
48 
49 typedef struct termination termination;
50 
51 struct termination {
52 #ifdef COVERAGE
53   volatile uint64_t flagged;
54 #else
55   volatile bool flagged;
56 #endif
57   volatile void *state;
58   int (*volatile terminate) (void *);
59 };
60 
61 // clang-format off
62 
63 typedef STACK (value) eliminated;
64 typedef STACK (import) imports;
65 typedef STACK (datarank) dataranks;
66 typedef STACK (watch) statches;
67 typedef STACK (watch *) patches;
68 
69 // clang-format on
70 
71 struct kitten;

 以上,(1)声明了kissat类型,有诸多子对象分别属于不同的类型;

            (2)宏定义SATCK(T)的具化类型之后被当作工作栈类型使用;见上述line63-67;

            (3)绝大多数函数名使用kissat打头命名,参数列表中第一个参数通常为kissat指针,其它参数类型的参数出现,表明该函数中还会用到不是kissat的数据成员使用;另internal.c中通过宏定义将kissat数据成员以大写标识的形式出现,如

      #define SCORES (&solver->scores)

因此带了参数kissat执行的函数能访问的数据成员是该类型的数据成员(含子对象)。

 

   

kissat类型声明中的数据成员与成员函数

 
  1 struct kissat {
  2 #if !defined(NDEBUG) || defined(METRICS)
  3   bool backbone_computing;
  4 #endif
  5 #ifdef LOGGING
  6   bool compacting;
  7 #endif
  8   bool extended;
  9   bool inconsistent;
 10   bool iterating;
 11   bool preprocessing;
 12   bool probing;
 13 #ifndef QUIET
 14   bool sectioned;
 15 #endif
 16   bool stable;
 17 #if !defined(NDEBUG) || defined(METRICS)
 18   bool transitive_reducing;
 19   bool vivifying;
 20 #endif
 21   bool warming;
 22   bool watching;
 23 
 24   bool large_clauses_watched_after_binary_clauses;  //最长名称的布尔型数据成员
 25 
 26   termination termination;
 27 
 28   unsigned vars;
 29   unsigned size;
 30   unsigned active;
 31   unsigned randec;
 32 
 33   ints export;
 34   ints units;
 35   imports import;
 36   extensions extend;
 37   unsigneds witness;
 38 
 39   assigned *assigned;
 40   flags *flags;
 41 
 42   mark *marks;
 43 
 44   value *values;
 45   phases phases;
 46 
 47   eliminated eliminated;
 48   unsigneds etrail;
 49 
 50   links *links;
 51   queue queue;
 52 
 53   heap scores;
 54   double scinc;
 55 
 56   heap schedule;
 57   double scoreshift;
 58 
 59   unsigned level;
 60   frames frames;
 61 
 62   unsigned_array trail;
 63   unsigned *propagate;
 64 
 65   unsigned best_assigned;
 66   unsigned target_assigned;
 67   unsigned unflushed;
 68   unsigned unassigned;
 69 
 70   unsigneds delayed;
 71 
 72 #if defined(LOGGING) || !defined(NDEBUG)
 73   unsigneds resolvent;
 74 #endif
 75   unsigned resolvent_size;
 76   unsigned antecedent_size;
 77 
 78   dataranks ranks;
 79 
 80   unsigneds analyzed;
 81   unsigneds levels;
 82   unsigneds minimize;
 83   unsigneds poisoned;
 84   unsigneds promote;
 85   unsigneds removable;
 86   unsigneds shrinkable;
 87 
 88   clause conflict;
 89 
 90   bool clause_satisfied;
 91   bool clause_shrink;
 92   bool clause_trivial;
 93 
 94   unsigneds clause;
 95   unsigneds shadow;
 96 
 97   arena arena;
 98   vectors vectors;
 99   reference first_reducible;
100   reference last_irredundant;
101   watches *watches;
102 
103   reference last_learned[4];
104 
105   sizes sorter;
106 
107   generator random;
108   averages averages[2];
109   unsigned tier1[2], tier2[2];
110   reluctant reluctant;
111 
112   bounds bounds;
113   classification classification;
114   delays delays;
115   enabled enabled;
116   limited limited;
117   limits limits;
118   remember last;
119   unsigned walked;
120 
121   mode mode;
122 
123   uint64_t ticks;
124 
125   format format;
126 
127   statches antecedents[2];
128   statches gates[2];
129   patches xorted[2];
130   unsigneds resolvents;
131   bool resolve_gate;
132 
133   struct kitten *kitten;
134 #ifdef METRICS
135   uint64_t *gate_eliminated;
136 #else
137   bool gate_eliminated;
138 #endif
139   bool sweep_incomplete;
140   unsigneds sweep_schedule;
141 
142 #if !defined(NDEBUG) || !defined(NPROOFS)
143   unsigneds added;
144   unsigneds removed;
145 #endif
146 
147 #if !defined(NDEBUG) || !defined(NPROOFS) || defined(LOGGING)
148   ints original;
149   size_t offset_of_last_original_clause;
150 #endif
151 
152 #ifndef QUIET
153   profiles profiles;
154 #endif
155 
156 #ifndef NOPTIONS
157   options options;
158 #endif
159 
160 #ifndef NDEBUG
161   checker *checker;   //该类型的定义居然在checker.c文件内
162 #endif
163 
164 #ifndef NPROOFS
165   proof *proof;
166 #endif
167 
168   statistics statistics;
169 };

注意区别: 类型unsigned、类型unsigneds 以及数据成员unsigned unassigned;

                   类型assigned;有没有assigneds? 以及数据成员 assigned *assigned;

另: ints;

 

在文件reference.h中:

                  typedef unsigned reference;

                  typedef STACK (reference) references;

 

在文件stack.h中

                 typedef STACK (char) chars;
                 typedef STACK (int) ints;
                 typedef STACK (size_t) sizes;
                  typedef STACK (unsigned) unsigneds;

   
 

//internal.c

从释放空间来了解求解器用到的向量——注意对应的是lit_idx还是var_idx; 向量是solver的数据成员还是全局的向量。

void kissat_release (kissat *solver) {
  kissat_require_initialized (solver);
  kissat_release_heap (solver, SCORES);
  kissat_release_heap (solver, &solver->schedule);
  kissat_release_vectors (solver);
  kissat_release_phases (solver);

  RELEASE_STACK (solver->export);
  RELEASE_STACK (solver->import);

  DEALLOC_VARIABLE_INDEXED (assigned);
  DEALLOC_VARIABLE_INDEXED (flags);
  DEALLOC_VARIABLE_INDEXED (links);

  DEALLOC_LITERAL_INDEXED (marks);
  DEALLOC_LITERAL_INDEXED (values);
  DEALLOC_LITERAL_INDEXED (watches);

  RELEASE_STACK (solver->import);
  RELEASE_STACK (solver->eliminated);
  RELEASE_STACK (solver->extend);
  RELEASE_STACK (solver->witness);
  RELEASE_STACK (solver->etrail);

  RELEASE_STACK (solver->delayed);

  RELEASE_STACK (solver->clause);
  RELEASE_STACK (solver->shadow);
#if defined(LOGGING) || !defined(NDEBUG)
  RELEASE_STACK (solver->resolvent);
#endif

  RELEASE_STACK (solver->arena);

  RELEASE_STACK (solver->units);
  RELEASE_STACK (solver->frames);
  RELEASE_STACK (solver->sorter);

  RELEASE_ARRAY (solver->trail, solver->size);

  RELEASE_STACK (solver->analyzed);
  RELEASE_STACK (solver->levels);
  RELEASE_STACK (solver->minimize);
  RELEASE_STACK (solver->poisoned);
  RELEASE_STACK (solver->promote);
  RELEASE_STACK (solver->removable);
  RELEASE_STACK (solver->shrinkable);
  RELEASE_STACK (solver->xorted[0]);
  RELEASE_STACK (solver->xorted[1]);

  RELEASE_STACK (solver->sweep_schedule);

  RELEASE_STACK (solver->ranks);

  RELEASE_STACK (solver->antecedents[0]);
  RELEASE_STACK (solver->antecedents[1]);
  RELEASE_STACK (solver->gates[0]);
  RELEASE_STACK (solver->gates[1]);
  RELEASE_STACK (solver->resolvents);

#if !defined(NDEBUG) || !defined(NPROOFS)
  RELEASE_STACK (solver->added);
  RELEASE_STACK (solver->removed);
#endif

#if !defined(NDEBUG) || !defined(NPROOFS) || defined(LOGGING)
  RELEASE_STACK (solver->original);
#endif

#ifndef QUIET
  RELEASE_STACK (solver->profiles.stack);
#endif

#ifndef NDEBUG
  kissat_release_checker (solver);
#endif
#if !defined(NDEBUG) && defined(METRICS)
  uint64_t leaked = solver->statistics.allocated_current;
  if (leaked)
    if (!getenv ("LEAK"))
      kissat_fatal ("internally leaking %" PRIu64 " bytes", leaked);
#endif

  kissat_free (0, solver, sizeof *solver);  
}

 

 

   
 

数据成员unflushed记录trail0层的文字数

相关操作:

//trail.c

1
void kissat_flush_trail (kissat *solver) { 2 assert (!solver->level); 3 assert (solver->unflushed); 4 assert (!solver->inconsistent); 5 assert (kissat_propagated (solver)); 6 assert (SIZE_ARRAY (solver->trail) == solver->unflushed); 7 LOG ("flushed %zu units from trail", SIZE_ARRAY (solver->trail)); 8 CLEAR_ARRAY (solver->trail); 9 kissat_reset_propagate (solver); 10 solver->unflushed = 0; 11 }

 

 

//inlineassign.h

 1 static inline void kissat_assign (kissat *solver, const bool probing,
 2                                   const unsigned level,
 3 #ifdef FAST_ASSIGN
 4                                   value *values, assigned *assigned,
 5 #endif
 6                                   bool binary, unsigned lit,
 7                                   unsigned reason) {
 8   const unsigned not_lit = NOT (lit);
 9 
10   watches watches = WATCHES (not_lit);
11   if (!kissat_empty_vector (&watches)) {
12     watch *w = BEGIN_WATCHES (watches);
13     __builtin_prefetch (w, 0, 1);
14   }
15 
16 #ifndef FAST_ASSIGN
17   value *values = solver->values;
18 #endif
19   assert (!values[lit]);
20   assert (!values[not_lit]);
21 
22   values[lit] = 1;
23   values[not_lit] = -1;
24 
25   assert (solver->unassigned > 0);
26   solver->unassigned--;
27 
28   if (!level) {  //0层
29     kissat_mark_fixed_literal (solver, lit);
30     assert (solver->unflushed < UINT_MAX);
31     solver->unflushed++;
32     if (reason != UNIT_REASON) {
33       CHECK_AND_ADD_UNIT (lit);
34       ADD_UNIT_TO_PROOF (lit);
35       reason = UNIT_REASON;
36       binary = false;
37     }
38   }
39 
40   const size_t trail = SIZE_ARRAY (solver->trail);
41   PUSH_ARRAY (solver->trail, lit);
42 
43   const unsigned idx = IDX (lit);
44 
45 #if !defined(PROBING_PROPAGATION)
46   if (!probing) {
47     const bool negated = NEGATED (lit);
48     const value new_value = BOOL_TO_VALUE (negated);
49     value *saved = &SAVED (idx);
50     *saved = new_value;
51   }
52 #endif
53 
54   struct assigned b;
55 
56   b.level = level;
57   b.trail = trail;
58 
59   b.analyzed = false;
60   b.binary = binary;
61   b.poisoned = false;
62   b.reason = reason;
63   b.removable = false;
64   b.shrinkable = false;
65 
66 #ifndef FAST_ASSIGN
67   assigned *assigned = solver->assigned;
68 #endif
69   struct assigned *a = assigned + idx;
70   *a = b;
71 }

 

 

关于单元文字在trail中如何标识可以查询下面相关标识名,从相应文件中分析。

  unflushed

  kissat_fast_assign

  kissat_flush_trail

  kissat_update_conflicts_and_trail

 

另查询:CHECK_AND_ADD_UNIT

 

 

//flags.h
typedef struct flags flags;

struct flags {
  bool active : 1;
  bool backbone0 : 1;
  bool backbone1 : 1;
  bool eliminate : 1;
  bool eliminated : 1;
  unsigned factor : 2;
  bool fixed : 1;
  bool subsume : 1;
  bool sweep : 1;
  bool transitive : 1;
};


//flags.c
//0层的元素单独进行mark
void kissat_mark_fixed_literal (kissat *solver, unsigned lit) {
  assert (VALUE (lit) > 0);
  const unsigned idx = IDX (lit);
  LOG ("marking internal %s as fixed", LOGVAR (idx));
  flags *f = FLAGS (idx);
  assert (f->active);
  assert (!f->eliminated);
  assert (!f->fixed);
  f->fixed = true;
  deactivate_variable (solver, f, idx);
  INC (units);
  int elit = kissat_export_literal (solver, lit);
  assert (elit);
  PUSH_STACK (solver->units, elit);
  LOG ("pushed external unit literal %d (internal %u)", elit, lit);
}

 

   
 

//checker.c中定义了两个类型,还有大量涉及Hash操作的内容。以下是该文件第50~125行的内容:

 1 #include "allocate.h"
 2 #include "inline.h"
 3 #include "sort.h"
 4 
 5 typedef struct hash hash;
 6 typedef struct bucket bucket;
 7 
 8 // clang-format off
 9 
10 typedef STACK (bucket*) buckets;
11 
12 // clang-format on
13 
14 struct bucket {
15   bucket *next;
16   unsigned size;
17   unsigned hash;
18   unsigned lits[];
19 };
20 
21 struct checker {
22   bool inconsistent;
23 
24   unsigned vars;
25   unsigned size;
26 
27   unsigned buckets;
28   unsigned hashed;
29 
30   bucket **table;
31 
32   buckets *watches;
33   bool *marks;
34   bool *large;
35   bool *used;
36   signed char *values;
37 
38   bool marked;
39   unsigneds imported;
40 
41   unsigneds trail;
42   unsigned propagated;
43 
44   unsigned nonces[32];
45 
46   uint64_t added;
47   uint64_t blocked;
48   uint64_t checked;
49   uint64_t collisions;
50   uint64_t decisions;
51   uint64_t propagations;
52   uint64_t pure;
53   uint64_t removed;
54   uint64_t satisfied;
55   uint64_t searches;
56   uint64_t unchecked;
57 };
58 
59 #define LOGIMPORTED3(...) \
60   LOGUNSIGNEDS3 (SIZE_STACK (checker->imported), \
61                  BEGIN_STACK (checker->imported), __VA_ARGS__)
62 
63 #define LOGLINE3(...) \
64   LOGUNSIGNEDS3 (bucket->size, bucket->lits, __VA_ARGS__)
65 
66 #define MAX_NONCES (sizeof checker->nonces / sizeof *checker->nonces)
67 
68 static inline bool less_unsigned (unsigned a, unsigned b) { return a < b; }
69 
70 static void sort_line (kissat *solver, checker *checker) {
71   SORT_STACK (unsigned, checker->imported, less_unsigned);
72   LOGIMPORTED3 ("sorted checker");
73 }

 

 

   

 

 

 

2.kissat求解器常用的宏定义:

  //internal.hpp
 

#define VARS (solver->vars)
#define LITS (2 * solver->vars)

#if 0
#define TIEDX (GET_OPTION (focusedtiers) ? 0 : solver->stable)
#define TIER1 (solver->tier1[TIEDX])
#define TIER2 (solver->tier2[TIEDX])
#else
#define TIER1 (solver->tier1[0])
#define TIER2 (solver->tier2[1])
#endif

#define SCORES (&solver->scores)

 

#define all_variables(IDX) \
unsigned IDX = 0, IDX##_END = solver->vars; \
IDX != IDX##_END; \
++IDX

#define all_literals(LIT) \
unsigned LIT = 0, LIT##_END = LITS; \
LIT != LIT##_END; \
++LIT

#define all_clauses(C) \
clause *C = (clause *) BEGIN_STACK (solver->arena), \
*const C##_END = (clause *) END_STACK (solver->arena), *C##_NEXT; \
C != C##_END && (C##_NEXT = kissat_next_clause (C), true); \
C = C##_NEXT

#define capacity_last_learned \
(sizeof solver->last_learned / sizeof *solver->last_learned)

#define real_end_last_learned (solver->last_learned + capacity_last_learned)

#define really_all_last_learned(REF_PTR) \
reference *REF_PTR = solver->last_learned, \
*REF_PTR##_END = real_end_last_learned; \
REF_PTR != REF_PTR##_END; \
REF_PTR++

   
 

 顺便复习宏定义的较晦涩的用法:

define中的三个特殊符号:#,##,#@

  1. #define Conn(x,y) x##y
  2. #define ToChar(x) #@x
  3. #define ToString(x) #x
(1)x##y表示什么?表示x连接y,举例说:
  1. int n = Conn(123,456); /* 结果就是n=123456;*/
  2. char* str = Conn("asdf", "adf"); /*结果就是 str = "asdfadf";*/
(2)再来看#@x,其实就是给x加上单引号,结果返回是一个const char。举例说:
char a = ToChar(1);结果就是a='1';
做个越界试验char a = ToChar(123);结果就错了;
但是如果你的参数超过四个字符,编译器就给给你报错了!
error C2015: too many characters in constant   :P

(3)#x,给x加双引号

char* str = ToString(123132);就成了str="123132";

   
 

 //inlineassign.h

#ifdef FAST_ASSIGN
#define kissat_assign kissat_fast_assign
#endif

   
 

 //statatic.h中关于宏定义的使用真是叹为观止——居然可以用来定义结构体的数据成员。以下是从第308行开始节选了部分代码。

......

typedef struct statistics statistics; #define MAX_GLUE_USED 127 struct statistics { #define COUNTER(NAME,VERBOSE,OTHER,UNITS,TYPE) \ uint64_t NAME; #define IGNORE(...) METRICS_COUNTERS_AND_STATISTICS #undef COUNTER #undef IGNORE struct { uint64_t glue[MAX_GLUE_USED + 1]; } used[2]; }; // clang-format on /*------------------------------------------------------------------------*/ #define CLAUSES (IRREDUNDANT_CLAUSES + BINARY_CLAUSES + REDUNDANT_CLAUSES) #define CONFLICTS (solver->statistics.conflicts) #define DECISIONS (solver->statistics.decisions) #define IRREDUNDANT_CLAUSES (solver->statistics.clauses_irredundant) #define LEARNED_CLAUSES (solver->statistics.learned) #define REDUNDANT_CLAUSES (solver->statistics.clauses_redundant) #define BINARY_CLAUSES (solver->statistics.clauses_binary) #define BINIRR_CLAUSES (BINARY_CLAUSES + IRREDUNDANT_CLAUSES) /*------------------------------------------------------------------------*/

......

 

上面代码节选中COUNTER是该文件中之前给出的另一个宏定义:

    #define STATISTIC COUNTER

在预定判别条件下宏定义之间互相通用:

 

宏定义METRICS_COUNTERS_AND_STATISTICS给出在类型statistics的数据成员。!!!

#define METRICS_COUNTERS_AND_STATISTICS \
\
  METRIC (allocated_collected, 2, PCNT_RESIDENT_SET, "%", "resident set") \
  METRIC (allocated_current, 2, PCNT_RESIDENT_SET, "%", "resident set") \
  METRIC (allocated_max, 2, PCNT_RESIDENT_SET, "%", "resident set") \
  STATISTIC (ands_eliminated, 1, PCNT_ELIMINATED, "%", "eliminated") \
  METRIC (ands_extracted, 1, PCNT_EXTRACTED, "%", "extracted") \
  METRIC (arena_enlarged, 1, PCNT_ARENA_RESIZED, "%", "resize") \
  METRIC (arena_garbage, 1, PCNT_RESIDENT_SET, "%", "resident set") \
  METRIC (arena_resized, 1, CONF_INT, "", "interval") \
  METRIC (arena_shrunken, 1, PCNT_ARENA_RESIZED, "%", "resize") \
  COUNTER (backbone_computations, 2, CONF_INT, "", "interval") \
  METRIC (backbone_implied, 1, PER_BACKBONE_UNIT, 0, "per unit") \
  METRIC (backbone_probes, 2, PER_VARIABLE, "", "per variable") \
  METRIC (backbone_propagations, 2, PCNT_PROPS, "%", "propagations") \
  METRIC (backbone_rounds, 2, PER_BACKBONE, 0, "per backbone") \
  COUNTER (backbone_ticks, 2, PCNT_TICKS, "%", "ticks") \
  STATISTIC (backbone_units, 1, PCNT_VARIABLES, "%", "variables") \
  METRIC (best_saved, 1, CONF_INT, "", "interval") \
  COUNTER (chronological, 1, PCNT_CONFLICTS, "%", "conflicts") \
  COUNTER (clauses_added, 2, PCNT_CLS_ADDED, "%", "added") \
  COUNTER (clauses_binary, 2, PCNT_CLS_ADDED, "%", "added") \
  STATISTIC (clauses_deleted, 1, PCNT_CLS_ADDED, "%", "added") \
  STATISTIC (clauses_factored, 1, PCNT_CLS_ADDED, "%", "added") \
  STATISTIC (clauses_improved, 1, PCNT_CLS_LEARNED, "%", "learned") \
  COUNTER (clauses_irredundant, 2, PCNT_CLS_ADDED, "%", "added") \
  STATISTIC (clauses_kept1, 1, PCNT_CLS_IMPROVED, "%", "improved") \
  STATISTIC (clauses_kept2, 1, PCNT_CLS_IMPROVED, "%", "improved") \
  STATISTIC (clauses_kept3, 1, PCNT_CLS_IMPROVED, "%", "improved") \
  COUNTER (clauses_learned, 2, PCNT_CONFLICTS, "%", "conflicts") \
  COUNTER (clauses_original, 2, PCNT_CLS_ADDED, "%", "added") \
  STATISTIC (clauses_promoted1, 1, PCNT_CLS_IMPROVED, "%", "improved") \
  STATISTIC (clauses_promoted2, 1, PCNT_CLS_IMPROVED, "%", "improved") \
  STATISTIC (clauses_reduced, 1, PCNT_CLS_LEARNED, "%", "learned") \
  STATISTIC (clauses_reduced_tier1, 1, PCNT_CLS_REDUCED, "%", "reduced") \
  STATISTIC (clauses_reduced_tier2, 1, PCNT_CLS_REDUCED, "%", "reduced") \
  STATISTIC (clauses_reduced_tier3, 1, PCNT_CLS_REDUCED, "%", "reduced") \
  COUNTER (clauses_redundant, 2, NO_SECONDARY, 0, 0) \
  STATISTIC (clauses_unfactored, 1, PCNT_CLS_FACTORED, "%", "factored") \
  COUNTER (clauses_used, 2, PCNT_CLS_LEARNED, "%", "learned") \
  COUNTER (clauses_used_focused, 2, PCNT_CLS_USED, "%", "used") \
  COUNTER (clauses_used_stable, 2, PCNT_CLS_USED, "%", "used") \
  COUNTER (closures, 2, CONF_INT, "", "interval") \
  METRIC (compacted, 1, PCNT_REDUCTIONS, "%", "reductions") \
  COUNTER (conflicts, 0, PER_SECOND, 0, "per second") \
  COUNTER (congruent, 1, PCNT_VARIABLES, "%", "variables") \
  STATISTIC (congruent_ands, 1, PCNT_CONGRUENT, "%", "congruent") \
  STATISTIC (congruent_arity, 1, PER_CONGRGATES, 0, "per gate") \
  STATISTIC (congruent_arity_ands, 1, PER_CONGRANDS, 0, "per AND") \
  STATISTIC (congruent_arity_xors, 1, PER_CONGRXORS, 0, "per XOR") \
  STATISTIC (congruent_binaries, 1, PCNT_CLS_ADDED, "%", "clauses added") \
  STATISTIC (congruent_ites, 1, PCNT_CONGRUENT, "%", "congruent") \
  STATISTIC (congruent_collisions, 1, PER_CONGRLOOKUP, 0, "per lookup") \
  STATISTIC (congruent_collisions_find, 1, PCNT_CONGRCOLS, "%", "collisions") \
  STATISTIC (congruent_collisions_index, 1, PCNT_CONGRCOLS, "%", "collisions") \
  STATISTIC (congruent_collisions_removed, 1, PCNT_CONGRCOLS, "%", "collisions") \
  STATISTIC (congruent_equivalences, 1, PCNT_CONGRUENT, "%", "congruent") \
  COUNTER (congruent_gates, 2, PER_CLOSURE, 0, "per closure") \
  COUNTER (congruent_gates_ands, 2, PCNT_CONGRGATES, "%", "gates") \
  COUNTER (congruent_gates_ites, 2, PCNT_CONGRGATES, "%", "gates") \
  COUNTER (congruent_gates_xors, 2, PCNT_CONGRGATES, "%", "gates") \
  STATISTIC (congruent_indexed, 1, PER_CONGRGATES, 0, "per gate") \
  STATISTIC (congruent_lookups, 1, PER_CONGRGATES, 0, "per gate") \
  STATISTIC (congruent_lookups_find, 1, PCNT_CONGRLOOKUP, "%", "lookups") \
  STATISTIC (congruent_lookups_removed, 1, PCNT_CONGRLOOKUP, "%", "lookups") \
  COUNTER (congruent_matched, 2, PCNT_CONGRUENT, "%", "congruent") \
  COUNTER (congruent_matched_ands, 2, PCNT_CONGRMATCHED, "%", "matched") \
  COUNTER (congruent_matched_ites, 2, PCNT_CONGRMATCHED, "%", "matched") \
  COUNTER (congruent_matched_xors, 2, PCNT_CONGRMATCHED, "%", "matched") \
  STATISTIC (congruent_rewritten, 1, PCNT_CONGRGATES, "%", "gates") \
  STATISTIC (congruent_rewritten_ands, 1, PCNT_CONGREWR, "%", "rewritten") \
  STATISTIC (congruent_rewritten_ites, 1, PCNT_CONGREWR, "%", "rewritten") \
  STATISTIC (congruent_rewritten_xors, 1, PCNT_CONGREWR, "%", "rewritten") \
  STATISTIC (congruent_simplified, 1, PCNT_CONGRGATES, "%", "gates") \
  STATISTIC (congruent_simplified_ands, 1, PCNT_CONGRSIMPS, "%", "simplified") \
  STATISTIC (congruent_simplified_ites, 1, PCNT_CONGRSIMPS, "%", "simplified") \
  STATISTIC (congruent_simplified_xors, 1, PCNT_CONGRSIMPS, "%", "simplified") \
  STATISTIC (congruent_subsumed, 1, PCNT_CLS_ORIGINAL, "%", "original") \
  STATISTIC (congruent_trivial_ite, 1, PCNT_CONGRUENT, "%", "congruent") \
  STATISTIC (congruent_unary, 1, PCNT_CONGRUENT, "%", "congruent") \
  STATISTIC (congruent_unary_ands, 1, PCNT_CONGRUNARY, "%", "unary") \
  STATISTIC (congruent_unary_ites, 1, PCNT_CONGRUNARY, "%", "unary") \
  STATISTIC (congruent_unary_xors, 1, PCNT_CONGRUNARY, "%", "unary") \
  STATISTIC (congruent_units, 1, PCNT_VARIABLES, "%", "variables") \
  STATISTIC (congruent_xors, 1, PCNT_CONGRUENT, "%", "congruent") \
  COUNTER (decisions, 0, PER_CONFLICT, 0, "per conflict") \
  METRIC (definitions_checked, 1, PCNT_ELIM_ATTEMPTS, "%", "attempts") \
  STATISTIC (definitions_eliminated, 1, PCNT_ELIMINATED, "%", "eliminated") \
  METRIC (definitions_extracted, 1, PCNT_EXTRACTED, "%", "extracted") \
  STATISTIC (definition_units, 1, PCNT_VARIABLES, "%", "variables") \
  METRIC (defragmentations, 1, CONF_INT, "", "interval") \
  METRIC (dense_garbage_collections, 2, PCNT_COLLECTIONS, "%", "collections") \
  METRIC (dense_propagations, 1, PCNT_PROPS, "%", "propagations") \
  METRIC (dense_ticks, 1, PCNT_TICKS, "%", "ticks") \
  METRIC (duplicated, 1, PCNT_CLS_ADDED, "%", "added") \
  STATISTIC (eagerly_subsumed, 1, PCNT_CLS_LEARNED, "%", "learned") \
  STATISTIC (eliminate_attempted, 1, PER_VARIABLE, 0, "per variable") \
  COUNTER (eliminated, 1, PCNT_VARIABLES, "%", "variables") \
  COUNTER (eliminate_resolutions, 2, PER_SECOND, 0, "per second") \
  STATISTIC (eliminate_units, 1, PCNT_VARIABLES, "%", "variables") \
  COUNTER (eliminations, 2, CONF_INT, "", "interval") \
  STATISTIC (equivalences_eliminated, 1, PCNT_ELIMINATED, "%", "eliminated") \
  METRIC (equivalences_extracted, 1, PCNT_EXTRACTED, "%", "extracted") \
  METRIC (extensions, 1, PCNT_SEARCHES, "%", "searches") \
  COUNTER (factored, 1, PCNT_VARIABLES, "%", "variables") \
  COUNTER (factorizations, 2, CONF_INT, "", "interval") \
  COUNTER (factor_ticks, 2, PCNT_TICKS, "%", "ticks") \
  COUNTER (fast_eliminated, 1, PCNT_ELIMINATED, "%", "eliminated") \
  COUNTER (fast_strengthened, 1, PCNT_STRENGTHENED, "%", "per strengthened") \
  COUNTER (fast_subsumed, 1, PCNT_SUBSUMED, "%", "per subsumed") \
  STATISTIC (fresh, 1, PCNT_VARIABLES, "%", "variables") \
  STATISTIC (flipped, 1, PER_WALKS, 0, "per walk") \
  METRIC (flushed, 2, PER_FIXED, 0, "per fixed") \
  METRIC (focused_decisions, 1, PCNT_DECISIONS, "%", "decisions") \
  METRIC (focused_modes, 1, CONF_INT, "", "interval") \
  METRIC (focused_propagations, 1, PCNT_PROPS, "%", "propagations") \
  METRIC (focused_restarts, 1, PCNT_RESTARTS, "%", "restarts") \
  METRIC (focused_ticks, 1, PCNT_TICKS, "%", "ticks") \
  COUNTER (forward_checks, 2, NO_SECONDARY, 0, 0) \
  COUNTER (forward_steps, 2, PER_FORWARD_CHECK, 0, "per check") \
  STATISTIC (forward_strengthened, 1, PCNT_STRENGTHENED, "%", "per strengthened") \
  STATISTIC (forward_subsumed, 1, PCNT_SUBSUMED, "%", "per subsumed") \
  METRIC (forward_subsumptions, 1, CONF_INT, "", "interval") \
  METRIC (garbage_collections, 2, CONF_INT, "", "interval") \
  METRIC (gates_checked, 1, PCNT_ELIM_ATTEMPTS, "%", "attempts") \
  STATISTIC (gates_eliminated, 1, PCNT_ELIMINATED, "%", "eliminated") \
  METRIC (gates_extracted, 1, PCNT_ELIM_ATTEMPTS, "%", "attempts") \
  STATISTIC (if_then_else_eliminated, 1, PCNT_ELIMINATED, "%", "eliminated") \
  METRIC (if_then_else_extracted, 1, PCNT_EXTRACTED, "%", "extracted") \
  METRIC (initial_decisions, 1, PCNT_DECISIONS, "%", "decisions") \
  COUNTER (iterations, 1, PCNT_VARIABLES, "%", "variables") \
  STATISTIC (jumped_reasons, 1, PCNT_PROPS, "%", "propagations") \
  STATISTIC (kitten_conflicts, 1, PER_KITTEN_SOLVED, 0, "per solved") \
  STATISTIC (kitten_decisions, 1, PER_KITTEN_SOLVED, 0, "per solved") \
  STATISTIC (kitten_flip, 1, NO_SECONDARY, 0, 0) \
  STATISTIC (kitten_flipped, 1, PCNT_KITTEN_FLIP, "%", "flip") \
  COUNTER (kitten_propagations, 2, PER_KITTEN_SOLVED, 0, "per solved") \
  STATISTIC (kitten_sat, 1, PCNT_KITTEN_SOLVED, "%", "solved") \
  COUNTER (kitten_solved, 2, NO_SECONDARY, 0, 0) \
  COUNTER (kitten_ticks, 2, PER_KITTEN_PROP, 0, "per prop") \
  STATISTIC (kitten_unknown, 1, PCNT_KITTEN_SOLVED, "%", "solved") \
  STATISTIC (kitten_unsat, 1, PCNT_KITTEN_SOLVED, "%", "solved") \
  METRIC (literals_bumped, 1, PER_CLS_LEARNED, 0, "per clause") \
  METRIC (literals_deduced, 1, PER_CLS_LEARNED, 0, "per clause") \
  COUNTER (literals_factor, 2, PER_VARIABLE, 0, "per variable") \
  STATISTIC (literals_factored, 1, PER_CLS_FACTORED, 0, "per factored") \
  METRIC (literals_learned, 1, PER_CLS_LEARNED, 0, "per clause") \
  METRIC (literals_minimized, 1, PCNT_LITS_DEDUCED, "%", "deduced") \
  METRIC (literals_minshrunken, 1, PCNT_LITS_SHRUNKEN, "%", "shrunken") \
  METRIC (literals_shrunken, 1, PCNT_LITS_DEDUCED, "%", "deduced") \
  STATISTIC (literals_unfactored, 2, PER_CLS_UNFACTORED, 0, "per unfactored") \
  METRIC (moved, 1, PCNT_REDUCTIONS, "%", "reductions") \
  STATISTIC (on_the_fly_strengthened, 1, PCNT_CONFLICTS, "%", "of conflicts") \
  STATISTIC (on_the_fly_subsumed, 1, PCNT_CONFLICTS, "%", "of conflicts") \
  METRIC (probing_propagations, 1, PCNT_PROPS, "%", "propagations") \
  COUNTER (probings, 2, CONF_INT, "", "interval") \
  COUNTER (probing_ticks, 2, PCNT_TICKS, "%", "ticks") \
  COUNTER (propagations, 0, PER_SECOND, "", "per second") \
  STATISTIC (queue_decisions, 1, PCNT_DECISIONS, "%", "decision") \
  STATISTIC (random_decisions, 1, PCNT_DECISIONS, "%", "decision") \
  COUNTER (random_sequences, 2, CONF_INT, "", "interval") \
  COUNTER (reductions, 1, CONF_INT, "", "interval") \
  COUNTER (reordered, 1, CONF_INT, "", "interval") \
  STATISTIC (reordered_focused, 1, PCNT_REORDERED, "%", "reordered") \
  STATISTIC (reordered_stable, 1, PCNT_REORDERED, "%", "reordered") \
  COUNTER (rephased, 1, CONF_INT, "", "interval") \
  METRIC (rephased_best, 1, PCNT_REPHASED, "%", "rephased") \
  METRIC (rephased_inverted, 1, PCNT_REPHASED, "%", "rephased") \
  METRIC (rephased_original, 1, PCNT_REPHASED, "%", "rephased") \
  METRIC (rephased_walking, 1, PCNT_REPHASED, "%", "rephased") \
  METRIC (rescaled, 2, CONF_INT, "", "interval") \
  COUNTER (restarts, 1, CONF_INT, "", "interval") \
  STATISTIC (restarts_levels, 1, PER_RESTART, 0, "per restart") \
  STATISTIC (restarts_reused_levels, 1, PCNT_RESTARTS_LEVELS, "%", "levels") \
  STATISTIC (restarts_reused_trails, 1, PCNT_RESTARTS, "%", "restarts") \
  COUNTER (retiered, 2, CONF_INT, "", "interval") \
  METRIC (saved_decisions, 1, PCNT_DECISIONS, "%", "decisions") \
  METRIC (score_decisions, 0, PCNT_DECISIONS, "%", "decision") \
  COUNTER (searches, 2, CONF_INT, "", "interval") \
  METRIC (search_propagations, 2, PCNT_PROPS, "%", "propagations") \
  COUNTER (search_ticks, 2, PCNT_TICKS, "%", "ticks") \
  METRIC (sparse_gcs, 2, PCNT_COLLECTIONS, "%", "collections") \
  METRIC (stable_decisions, 1, PCNT_DECISIONS, "%", "decisions") \
  METRIC (stable_modes, 2, CONF_INT, "", "interval") \
  METRIC (stable_propagations, 1, PCNT_PROPS, "%", "propagations") \
  METRIC (stable_restarts, 1, PCNT_RESTARTS, "%", "restarts") \
  METRIC (stable_ticks, 2, PCNT_TICKS, "%", "ticks") \
  COUNTER (strengthened, 1, PCNT_SUBSUMPTION_CHECK, "%", "checks") \
  COUNTER (substituted, 1, PCNT_VARIABLES, "%", "variables") \
  COUNTER (substitute_ticks, 2, PCNT_TICKS, "%", "ticks") \
  STATISTIC (substitute_units, 1, PCNT_VARIABLES, "%", "variables") \
  STATISTIC (substitutions, 2, CONF_INT, "", "interval") \
  COUNTER (subsumed, 1, PCNT_SUBSUMPTION_CHECK, "%", "checks") \
  COUNTER (subsumption_checks, 2, NO_SECONDARY, 0, 0) \
  COUNTER (sweep, 2, CONF_INT, "", "interval") \
  STATISTIC (sweep_clauses, 1, PER_SWEEP_VARIABLES, 0, "per sweep_variables") \
  COUNTER (sweep_completed, 2, SWEEPS_PER_COMPLETED, 0, "sweeps") \
  STATISTIC (sweep_depth, 1, PER_SWEEP_VARIABLES, 0, "per sweep_variables") \
  STATISTIC (sweep_environment, 1, PER_SWEEP_VARIABLES, 0, "per sweep_variables") \
  COUNTER (sweep_equivalences, 2, PCNT_VARIABLES, "%", "variables") \
  STATISTIC (sweep_fixed_backbone, 1, PER_SWEEP_VARIABLES, 0, "per sweep_variables") \
  STATISTIC (sweep_flip_backbone, 1, PER_SWEEP_VARIABLES, 0, "per sweep_variables") \
  STATISTIC (sweep_flipped_backbone, 1, PCNT_SWEEP_FLIP_BACKBONE, "%", "sweep_flip_backbone") \
  STATISTIC (sweep_flip_equivalences, 1, PER_SWEEP_VARIABLES, 0, "per sweep_variables") \
  STATISTIC (sweep_flipped_equivalences, 1, PCNT_SWEEP_FLIP_EQUIVALENCES, "%", "sweep_flip_equivalences") \
  STATISTIC (sweep_sat, 1, PCNT_SWEEP_SOLVED, "%", "sweep_solved") \
  STATISTIC (sweep_sat_backbone, 1, PCNT_SWEEP_SOLVED_BACKBONE, "%", "sweep_solved_backbone") \
  STATISTIC (sweep_sat_equivalences, 1, PCNT_SWEEP_SOLVED_EQUIVALENCES, "%", "sweep_solved_equivalences") \
  COUNTER (sweep_solved, 2, PCNT_KITTEN_SOLVED, "%", "kitten_solved") \
  STATISTIC (sweep_solved_backbone, 1, PCNT_SWEEP_SOLVED, "%", "sweep_solved") \
  STATISTIC (sweep_solved_equivalences, 1, PCNT_SWEEP_SOLVED, "%", "sweep_solved") \
  STATISTIC (sweep_unknown_backbone, 1, PCNT_SWEEP_SOLVED_BACKBONE, "%", "sweep_solved_backbone") \
  STATISTIC (sweep_unknown_equivalences, 1, PCNT_SWEEP_SOLVED_EQUIVALENCES, "%", "sweep_solved_equivalences") \
  COUNTER (sweep_units, 2, PCNT_VARIABLES, "%", "variables") \
  STATISTIC (sweep_unsat, 1, PCNT_SWEEP_SOLVED, "%", "sweep_solved") \
  STATISTIC (sweep_unsat_backbone, 1, PCNT_SWEEP_SOLVED_BACKBONE, "%", "sweep_solve_backbone") \
  STATISTIC (sweep_unsat_equivalences, 1, PCNT_SWEEP_SOLVED_EQUIVALENCES, "%", "sweep_solve_equivalences") \
  STATISTIC (sweep_variables, 1, PCNT_VARIABLES, "%", "variables") \
  COUNTER (switched, 0, CONF_INT, "", "interval") \
  METRIC (target_decisions, 1, PCNT_DECISIONS, "%", "decisions") \
  METRIC (target_saved, 1, CONF_INT, "", "interval") \
  STATISTIC (ticks, 2, PER_PROPAGATION, 0, "per prop") \
  METRIC (transitive_probes, 2, PER_VARIABLE, "", "per variable") \
  METRIC (transitive_propagations, 2, PCNT_PROPS, "%", "propagations") \
  METRIC (transitive_reduced, 1, PCNT_CLS_ADDED, "%", "added") \
  METRIC (transitive_reductions, 1, CONF_INT, "", "interval") \
  COUNTER (transitive_ticks, 2, PCNT_TICKS, "%", "ticks") \
  METRIC (transitive_units, 1, PCNT_VARIABLES, "%", "variables") \
  COUNTER (units, 2, PCNT_VARIABLES, "%", "variables") \
  COUNTER (variables_activated, 2, PER_VARIABLE, 0, "per variable") \
  COUNTER (variables_eliminate, 2, PER_VARIABLE, 0, "variables") \
  COUNTER (variables_extension, 2, PER_VARIABLE, 0, "per variable") \
  COUNTER (variables_factor, 2, PER_VARIABLE, 0, "per variable") \
  COUNTER (variables_original, 2, PER_VARIABLE, 0, "per variable") \
  COUNTER (variables_subsume, 2, PER_VARIABLE, 0, "per variable") \
  METRIC (vectors_defrags_needed, 1, PCNT_DEFRAGS, "%", "defrags") \
  METRIC (vectors_enlarged, 2, CONF_INT, "", "interval") \
  COUNTER (vivifications, 2, CONF_INT, "", "interval") \
  COUNTER (vivified, 1, PCNT_VIVIFY_CHECK, "%", "checks") \
  STATISTIC (vivified_asym, 1, PCNT_VIVIFIED, "%", "vivified") \
  STATISTIC (vivified_implied, 1, PCNT_VIVIFIED, "%", "vivified") \
  STATISTIC (vivified_instantiated, 1, PCNT_VIVIFIED, "%", "vivified") \
  STATISTIC (vivified_instirr, 1, PCNT_VIVIFY_INST, "%", "instantiated") \
  STATISTIC (vivified_instred, 1, PCNT_VIVIFY_INST, "%", "instantiated") \
  STATISTIC (vivified_irredundant, 1, PCNT_VIVIFIED, "%", "vivified") \
  STATISTIC (vivified_promoted, 1, PCNT_VIVIFIED, "%", "vivified") \
  STATISTIC (vivified_shrunken, 1, PCNT_VIVIFIED, "%", "vivified") \
  STATISTIC (vivified_shrunkirr, 1, PCNT_VIVIFY_SHRUNKEN, "%", "shrunken") \
  STATISTIC (vivified_shrunkred, 1, PCNT_VIVIFY_SHRUNKEN, "%", "shrunken") \
  STATISTIC (vivified_subirr, 1, PCNT_VIVIFY_SUB, "%", "subsumed") \
  STATISTIC (vivified_subred, 1, PCNT_VIVIFY_SUB, "%", "subsumed") \
  STATISTIC (vivified_subsumed, 1, PCNT_VIVIFIED, "%", "vivified") \
  STATISTIC (vivified_tier1, 1, PCNT_VIVIFIED, "%", "vivified") \
  STATISTIC (vivified_tier2, 1, PCNT_VIVIFIED, "%", "vivified") \
  STATISTIC (vivified_tier3, 1, PCNT_VIVIFIED, "%", "vivified") \
  STATISTIC (vivified_unlearn, 1, PCNT_VIVIFIED, "%", "vivified") \
  COUNTER (vivify_checks, 2, PER_VIVIFICATION, "", "per vivify") \
  COUNTER (vivify_probes, 2, PER_VIVIFY_CHECK, 0, "per check") \
  STATISTIC (vivify_propagations, 2, PCNT_PROPS, "%", "propagations") \
  COUNTER (vivify_reused, 2, PCNT_VIVIFY_PROBES, "%", "probes") \
  STATISTIC (vivify_ticks, 2, PCNT_TICKS, "%", "ticks") \
  STATISTIC (vivify_units, 1, PCNT_VARIABLES, "%", "variables") \
  METRIC (walk_decisions, 1, PCNT_WALKS, "%", "walks") \
  STATISTIC (walk_improved, 1, PCNT_WALKS, "%", "walks") \
  METRIC (walk_previous, 1, PCNT_WALKS, "%", "walks") \
  COUNTER (walks, 1, CONF_INT, "", "interval") \
  COUNTER (walk_steps, 2, PER_FLIPPED, 0, "per flipped") \
  STATISTIC (warming_conflicts, 1, PER_WALKS, 0, "per walk") \
  COUNTER (warming_decisions, 2, PER_WALKS, 0, "per walk") \
  COUNTER (warming_propagations, 2, PCNT_PROPS, "%", "propagations") \
  COUNTER (warmups, 2, PCNT_WALKS, "%", "walks") \
  METRIC (weakened, 1, PCNT_CLS_ADDED, "%", "added")

// clang-format on
#define METRICS_COUNTERS_AND_STATISTICS

 

 

   
   
   
   
   
   
   
   
   
   
   
   

 

3.主函数中调用kissat类型指针solver的函数及其相关函数:

 
//internal.hpp
1
static inline unsigned kissat_assigned (kissat *solver) { 2 assert (VARS >= solver->unassigned); 3 return VARS - solver->unassigned; 4 }

//区别于没有ed的传播赋值函数函数 kissat_assign (kissat *solver);

 

 

 //inlineassign.h
1
#ifdef FAST_ASSIGN 2 #define kissat_assign kissat_fast_assign 3 #endif 4 5 static inline void kissat_assign (kissat *solver, const bool probing, 6 const unsigned level, 7 #ifdef FAST_ASSIGN 8 value *values, assigned *assigned, 9 #endif 10 bool binary, unsigned lit, 11 unsigned reason) 12 { 13 ...... 14 } //这个函数至少有6各输出参数

 

   
 

 与文字对应的属性设置相关的数据结构:可以从以下函数中进行分析学习。

 //inline.h
1
static inline void kissat_mark_removed_literal (kissat *solver, 2 unsigned lit) { 3 const unsigned idx = IDX (lit); 4 flags *flags = FLAGS (idx); 5 if (flags->fixed) 6 return; 7 if (!flags->eliminate) { 8 LOG ("marking %s to be eliminated", LOGVAR (idx)); 9 flags->eliminate = true; 10 INC (variables_eliminate); 11 } 12 }
1 static inline void kissat_push_analyzed (kissat *solver, assigned *assigned,
2                                          unsigned idx) {
3   assert (idx < VARS);
4   struct assigned *a = assigned + idx;
5   assert (!a->analyzed);
6   a->analyzed = true;
7   PUSH_STACK (solver->analyzed, idx);
8   LOG2 ("%s analyzed", LOGVAR (idx));
9 }
1 static inline void
2 kissat_push_removable (kissat *solver, assigned *assigned, unsigned idx) {
3   assert (idx < VARS);
4   struct assigned *a = assigned + idx;
5   assert (!a->removable);
6   a->removable = true;
7   PUSH_STACK (solver->removable, idx);
8   LOG2 ("%s removable", LOGVAR (idx));
9 }
1 static inline void kissat_push_poisoned (kissat *solver, assigned *assigned,
2                                          unsigned idx) {
3   assert (idx < VARS);
4   struct assigned *a = assigned + idx;
5   assert (!a->poisoned);
6   a->poisoned = true;
7   PUSH_STACK (solver->poisoned, idx);
8   LOG2 ("%s poisoned", LOGVAR (idx));
9 }
static inline void
kissat_push_shrinkable (kissat *solver, assigned *assigned, unsigned idx) {
  assert (idx < VARS);
  struct assigned *a = assigned + idx;
  assert (!a->shrinkable);
  a->shrinkable = true;
  PUSH_STACK (solver->shrinkable, idx);
  LOG2 ("%s shrinkable", LOGVAR (idx));
}

 

已知文字后获得对应的观察序列

  const unsigned not_lit = NOT (lit);

  watches watches = WATCHES (not_lit);

 

   
 

子句的类型声明:

struct clause {
  unsigned glue : LD_MAX_GLUE;

  bool garbage : 1;
  bool quotient : 1;
  bool reason : 1;
  bool redundant : 1;
  bool shrunken : 1;
  bool subsume : 1;
  bool swept : 1;
  bool vivify : 1;

  unsigned used : LD_MAX_USED;

  unsigned searched;
  unsigned size;

  unsigned lits[3];
};

 

 

 

 从子句的构造来看,Kissat求解器的子句分为三类:

original;irredundant;  redundant;

 1 reference kissat_new_original_clause (kissat *solver) {
 2   const unsigned size = SIZE_STACK (solver->clause);
 3   unsigned *lits = BEGIN_STACK (solver->clause);
 4   kissat_sort_literals (solver, size, lits);
 5   reference res = new_clause (solver, true, false, 0, size, lits);
 6   return res;
 7 }
 8 
 9 reference kissat_new_irredundant_clause (kissat *solver) {
10   const unsigned size = SIZE_STACK (solver->clause);
11   unsigned *lits = BEGIN_STACK (solver->clause);
12   return new_clause (solver, false, false, 0, size, lits);
13 }
14 
15 reference kissat_new_redundant_clause (kissat *solver, unsigned glue) {
16   const unsigned size = SIZE_STACK (solver->clause);
17   unsigned *lits = BEGIN_STACK (solver->clause);
18   return new_clause (solver, false, true, glue, size, lits);
19 }

 

 1 static reference new_clause (kissat *solver, bool original, bool redundant,
 2                              unsigned glue, unsigned size, unsigned *lits) {
 3   reference res;
 4   if (size == 2)
 5     res = new_binary_clause (solver, original, true, lits[0], lits[1]);
 6   else
 7     res = new_large_clause (solver, original, redundant, glue, size, lits);
 8   kissat_defrag_watches_if_needed (solver);
 9   return res;
10 }

 

 1 static void inc_clause (kissat *solver, bool original, bool redundant,
 2                         bool binary) {
 3   if (binary)
 4     INC (clauses_binary);
 5   else if (redundant)
 6     INC (clauses_redundant);
 7   else
 8     INC (clauses_irredundant);
 9   INC (clauses_added);
10   if (original)
11     INC (clauses_original);
12 }
13 
14 static void dec_clause (kissat *solver, bool redundant, bool binary) {
15   if (binary)
16     DEC (clauses_binary);
17   else if (redundant)
18     DEC (clauses_redundant);
19   else
20     DEC (clauses_irredundant);
21 }

 

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

4. 相关CDCL模块的学习

4.1 决策变元选择机制

 

从重启模块reuse中学习相关代码可知:维护了两个活跃度,scores堆和links链表;它们对应两种决策变元选择机制:

    solver->stable

    focused_decisions

//另有决策机制,后续了解。见decide.c

              solver->warming

    solver->randec

 

//restart.c

static unsigned reuse_stable_trail (kissat *solver) {
  const heap *const scores = SCORES;
  const unsigned next_idx = kissat_next_decision_variable (solver);
  const double limit = kissat_get_heap_score (scores, next_idx);
  unsigned level = solver->level, res = 0;
  while (res < level) {
    frame *f = &FRAME (res + 1);
    const unsigned idx = IDX (f->decision);
    const double score = kissat_get_heap_score (scores, idx);
    if (score <= limit)
      break;
    res++;
  }
  return res;
}

static unsigned reuse_focused_trail (kissat *solver) {
  const links *const links = solver->links;
  const unsigned next_idx = kissat_next_decision_variable (solver);
  const unsigned limit = links[next_idx].stamp;
  LOG ("next decision variable stamp %u", limit);
  unsigned level = solver->level, res = 0;
  while (res < level) {
    frame *f = &FRAME (res + 1);
    const unsigned idx = IDX (f->decision);
    const unsigned score = links[idx].stamp;
    if (score <= limit)
      break;
    res++;
  }
  return res;
}

 

//从决策变元选择相关代码学习:

决策变元相关信息被专门保留在 frames中;——与决策变元相关的技术是否需要重点研究分析?

#ifndef _frames_h_INCLUDED
#define _frames_h_INCLUDED

#include "literal.h"
#include "stack.h"

#include <stdbool.h>

typedef struct frame frame;
typedef struct slice slice;

struct frame {
  bool promote;
  unsigned decision;
  unsigned trail;
  unsigned used;
#ifndef NDEBUG
  unsigned saved;
#endif
};

// clang-format off

typedef STACK (frame) frames;

// clang-format on

struct kissat;

#define FRAME(LEVEL) (PEEK_STACK (solver->frames, (LEVEL)))

#endif
frame.h

 

//inlineframe.h

static inline void kissat_push_frame (kissat *solver, unsigned decision) {
  assert (!solver->level || decision != UINT_MAX);
  const size_t trail = SIZE_ARRAY (solver->trail);
  frame frame;
  frame.decision = decision;
  frame.promote = false;
  frame.trail = trail;
  frame.used = 0;
  PUSH_STACK (solver->frames, frame);
}

 

//决策变元选择机制的体现代码

//decide.c

unsigned kissat_next_decision_variable (kissat *solver) {
#ifdef LOGGING
  const char *type = 0;
#endif
  unsigned res = next_random_decision (solver);
  if (res == INVALID_IDX) {
    if (solver->stable) {
#ifdef LOGGING
      type = "maximum score";
#endif
      res = largest_score_unassigned_variable (solver);
      INC (score_decisions);
    } else {
#ifdef LOGGING
      type = "dequeued";
#endif
      res = last_enqueued_unassigned_variable (solver);
      INC (queue_decisions);
    }
  } else {
#ifdef LOGGING
    type = "random";
#endif
    INC (random_decisions);
  }
  LOG ("next %s decision %s", type, LOGVAR (res));
  return res;
}

 

 

//决策变元的赋值过程

//search.c

int kissat_search (kissat *solver) {
  REPORT (0, '*');
  int res = 0;
  if (solver->inconsistent)
    res = 20;
  if (!res && GET_OPTION (luckyearly))
    res = kissat_lucky (solver);
  if (!res && kissat_preprocessing (solver))
    res = kissat_preprocess (solver);
  if (!res && GET_OPTION (luckylate))
    res = kissat_lucky (solver);
  if (!res)
    kissat_classify (solver);
  if (!res && searching (solver)) {
    start_search (solver);
    while (!res) {
      clause *conflict = kissat_search_propagate (solver);
      if (conflict)
        res = kissat_analyze (solver, conflict);
      else if (solver->iterating)
        iterate (solver);
      else if (!solver->unassigned)
        res = 10;
      else if (TERMINATED (search_terminated_1))
        break;
      else if (kissat_reducing (solver))
        res = kissat_reduce (solver);
      else if (kissat_switching_search_mode (solver))
        kissat_switch_search_mode (solver);
      else if (kissat_restarting (solver))
        kissat_restart (solver);
      else if (kissat_reordering (solver))
        kissat_reorder (solver);
      else if (kissat_rephasing (solver))
        kissat_rephase (solver);
      else if (kissat_probing (solver))
        res = kissat_probe (solver);
      else if (kissat_eliminating (solver))
        res = kissat_eliminate (solver);
      else if (conflict_limit_hit (solver))
        break;
      else if (decision_limit_hit (solver))
        break;
      else
        kissat_decide (solver);
    }
    stop_search (solver);
  }
  report_search_result (solver, res);
  return res;
}

 

//decide.c

void kissat_decide (kissat *solver) {
  START (decide);
  assert (solver->unassigned);
  if (solver->warming)
    INC (warming_decisions);
  else {
    INC (decisions);
    if (solver->stable)
      INC (stable_decisions);
    else
      INC (focused_decisions);
  }
  solver->level++;
  assert (solver->level != INVALID_LEVEL);
  const unsigned idx = kissat_next_decision_variable (solver);  //决策变元选择机制被使用
  const value value = kissat_decide_phase (solver, idx);
  unsigned lit = LIT (idx);
  if (value < 0)
    lit = NOT (lit);
  kissat_push_frame (solver, lit);
  assert (solver->level < SIZE_STACK (solver->frames));
  LOG ("decide literal %s", LOGLIT (lit));
  kissat_assign_decision (solver, lit);
  STOP (decide);
}

void kissat_internal_assume (kissat *solver, unsigned lit) {
  assert (solver->unassigned);
  assert (!VALUE (lit));
  solver->level++;
  assert (solver->level != INVALID_LEVEL);
  kissat_push_frame (solver, lit);
  assert (solver->level < SIZE_STACK (solver->frames));
  LOG ("assuming literal %s", LOGLIT (lit));
  kissat_assign_decision (solver, lit);
}

 

//assign.c

void kissat_assign_decision (kissat *solver, unsigned lit) {
  kissat_assign (solver, solver->probing, solver->level, false, lit,
                 DECISION_REASON);
  LOG ("assign %s decision", LOGLIT (lit));
}

 

//inlineassign.h

#ifdef FAST_ASSIGN
#define kissat_assign kissat_fast_assign #endif static inline void kissat_assign (kissat *solver, const bool probing, const unsigned level, #ifdef FAST_ASSIGN value *values, assigned *assigned, #endif bool binary, unsigned lit, unsigned reason) { const unsigned not_lit = NOT (lit); watches watches = WATCHES (not_lit); if (!kissat_empty_vector (&watches)) { watch *w = BEGIN_WATCHES (watches); __builtin_prefetch (w, 0, 1); } #ifndef FAST_ASSIGN value *values = solver->values; #endif assert (!values[lit]); assert (!values[not_lit]); values[lit] = 1; values[not_lit] = -1; assert (solver->unassigned > 0); solver->unassigned--; if (!level) { kissat_mark_fixed_literal (solver, lit); assert (solver->unflushed < UINT_MAX); solver->unflushed++; if (reason != UNIT_REASON) { CHECK_AND_ADD_UNIT (lit); ADD_UNIT_TO_PROOF (lit); reason = UNIT_REASON; binary = false; } } const size_t trail = SIZE_ARRAY (solver->trail); PUSH_ARRAY (solver->trail, lit); const unsigned idx = IDX (lit); #if !defined(PROBING_PROPAGATION) if (!probing) { const bool negated = NEGATED (lit); const value new_value = BOOL_TO_VALUE (negated); value *saved = &SAVED (idx); *saved = new_value; } #endif struct assigned b; b.level = level; b.trail = trail; b.analyzed = false; b.binary = binary; b.poisoned = false; b.reason = reason; b.removable = false; b.shrinkable = false; #ifndef FAST_ASSIGN assigned *assigned = solver->assigned; #endif struct assigned *a = assigned + idx; *a = b; }

 

 

   

 4.2 相位选择机制

 
//decide.c

void kissat_decide (kissat *solver) {
  START (decide);
  assert (solver->unassigned);
  if (solver->warming)
    INC (warming_decisions);
  else {
    INC (decisions);
    if (solver->stable)
      INC (stable_decisions);
    else
      INC (focused_decisions);
  }
  solver->level++;
  assert (solver->level != INVALID_LEVEL);
  const unsigned idx = kissat_next_decision_variable (solver);
  const value value = kissat_decide_phase (solver, idx);
  unsigned lit = LIT (idx);
  if (value < 0)
    lit = NOT (lit);
  kissat_push_frame (solver, lit);
  assert (solver->level < SIZE_STACK (solver->frames));
  LOG ("decide literal %s", LOGLIT (lit));
  kissat_assign_decision (solver, lit);
  STOP (decide);
}

 

//decide.c

int kissat_decide_phase (kissat *solver, unsigned idx) {
  bool force = GET_OPTION (forcephase);

  value *target;
  if (force)
    target = 0;
  else if (!GET_OPTION (target))
    target = 0;
  else if (solver->stable || GET_OPTION (target) > 1)
    target = solver->phases.target + idx;
  else
    target = 0;

  value *saved;
  if (force)
    saved = 0;
  else if (GET_OPTION (phasesaving))
    saved = solver->phases.saved + idx;
  else
    saved = 0;

  value res = 0;

  if (!solver->stable) {
    switch ((solver->statistics.switched >> 1) & 7) {
    case 1:
      res = INITIAL_PHASE;
      break;
    case 3:
      res = -INITIAL_PHASE;
      break;
    }
  }

  if (!res && target && (res = *target)) {
    LOG ("%s uses target decision phase %d", LOGVAR (idx), (int) res);
    INC (target_decisions);
  }

  if (!res && saved && (res = *saved)) {
    LOG ("%s uses saved decision phase %d", LOGVAR (idx), (int) res);
    INC (saved_decisions);
  }

  if (!res) {
    res = INITIAL_PHASE;
    LOG ("%s uses initial decision phase %d", LOGVAR (idx), (int) res);
    INC (initial_decisions);
  }
  assert (res);

  return res < 0 ? -1 : 1;
}

 

 

 

   

 

4.3 布尔约束传播模块

 

 确定传播文字均在solver->trail中;

有三类文字:

    0层的单元文字

    各层决策文字

    蕴涵传播的文字

 

 

//传播调用过程:

//search.c

int
kissat_search (kissat *solver) { REPORT (0, '*'); int res = 0; if (solver->inconsistent) res = 20; if (!res && GET_OPTION (luckyearly)) res = kissat_lucky (solver); if (!res && kissat_preprocessing (solver)) res = kissat_preprocess (solver); if (!res && GET_OPTION (luckylate)) res = kissat_lucky (solver); if (!res) kissat_classify (solver); if (!res && searching (solver)) { start_search (solver); while (!res) { clause *conflict = kissat_search_propagate (solver); if (conflict) res = kissat_analyze (solver, conflict); else if (solver->iterating) iterate (solver); else if (!solver->unassigned) res = 10; else if (TERMINATED (search_terminated_1)) break; else if (kissat_reducing (solver)) res = kissat_reduce (solver); else if (kissat_switching_search_mode (solver)) kissat_switch_search_mode (solver); else if (kissat_restarting (solver)) kissat_restart (solver); else if (kissat_reordering (solver)) kissat_reorder (solver); else if (kissat_rephasing (solver)) kissat_rephase (solver); else if (kissat_probing (solver)) res = kissat_probe (solver); else if (kissat_eliminating (solver)) res = kissat_eliminate (solver); else if (conflict_limit_hit (solver)) break; else if (decision_limit_hit (solver)) break; else kissat_decide (solver); } stop_search (solver); } report_search_result (solver, res); return res; }

 

//propsearch.c

clause *kissat_search_propagate (kissat *solver) { assert (!solver->probing); assert (solver->watching); assert (!solver->inconsistent); START (propagate); solver->ticks = 0; const unsigned *saved_propagate = solver->propagate; clause *conflict = search_propagate (solver); update_search_propagation_statistics (solver, saved_propagate); kissat_update_conflicts_and_trail (solver, conflict, true); if (conflict && solver->randec) { if (!--solver->randec) kissat_very_verbose (solver, "last random decision conflict"); else if (solver->randec == 1) kissat_very_verbose (solver, "one more random decision conflict to go"); else kissat_very_verbose (solver, "%s more random decision conflicts to go", FORMAT_COUNT (solver->randec)); } STOP (propagate); return conflict; }

 

//propsearch.c

  #define PROPAGATE_LITERAL search_propagate_literal
  #define PROPAGATION_TYPE "search"



static
clause *search_propagate (kissat *solver) { clause *res = 0; unsigned *propagate = solver->propagate; while (!res && propagate != END_ARRAY (solver->trail)) res = search_propagate_literal (solver, *propagate++); solver->propagate = propagate; return res; }

 

// porplit.h

static inline clause *PROPAGATE_LITERAL (kissat *solver,
#if defined(PROBING_PROPAGATION)
                                         const clause *const ignore,
#endif
                                         const unsigned lit) {
  assert (solver->watching);
  LOG (PROPAGATION_TYPE " propagating %s", LOGLIT (lit));
  assert (VALUE (lit) > 0);
  assert (EMPTY_STACK (solver->delayed));

  watches *const all_watches = solver->watches;
  ward *const arena = BEGIN_STACK (solver->arena);
  assigned *const assigned = solver->assigned;
  value *const values = solver->values;

  const unsigned not_lit = NOT (lit);

  assert (not_lit < LITS);
  watches *watches = all_watches + not_lit;

  watch *const begin_watches = BEGIN_WATCHES (*watches);
  const watch *const end_watches = END_WATCHES (*watches);

  watch *q = begin_watches;
  const watch *p = q;

  unsigneds *const delayed = &solver->delayed;
  assert (EMPTY_STACK (*delayed));

  const size_t size_watches = SIZE_WATCHES (*watches);
  uint64_t ticks = 1 + kissat_cache_lines (size_watches, sizeof (watch));
  const unsigned idx = IDX (lit);
  struct assigned *const a = assigned + idx;
  const bool probing = solver->probing;
  const unsigned level = a->level;
  clause *res = 0;

  while (p != end_watches) {
    const watch head = *q++ = *p++;
    const unsigned blocking = head.blocking.lit;
    assert (VALID_INTERNAL_LITERAL (blocking));
    const value blocking_value = values[blocking];
    const bool binary = head.type.binary;
    watch tail;
    if (!binary)
      tail = *q++ = *p++;
    if (blocking_value > 0)
      continue;
    if (binary) {
      if (blocking_value < 0) {
        res = kissat_binary_conflict (solver, not_lit, blocking);
#ifndef CONTINUE_PROPAGATING_AFTER_CONFLICT
        break;
#endif
      } else {
        assert (!blocking_value);
        kissat_fast_binary_assign (solver, probing, level, values, assigned,
                                   blocking, not_lit);
        ticks++;
      }
    } else {
      const reference ref = tail.raw;
      assert (ref < SIZE_STACK (solver->arena));
      clause *const c = (clause *) (arena + ref);
      ticks++;
      if (c->garbage) {
        q -= 2;
        continue;
      }
      unsigned *const lits = BEGIN_LITS (c);
      const unsigned other = lits[0] ^ lits[1] ^ not_lit;
      assert (lits[0] != lits[1]);
      assert (VALID_INTERNAL_LITERAL (other));
      assert (not_lit != other);
      assert (lit != other);
      const value other_value = values[other];
      if (other_value > 0) {
        q[-2].blocking.lit = other;
        continue;
      }
      const unsigned *const end_lits = lits + c->size;
      unsigned *const searched = lits + c->searched;
      assert (c->lits + 2 <= searched);
      assert (searched < end_lits);
      unsigned *r, replacement = INVALID_LIT;
      value replacement_value = -1;
      for (r = searched; r != end_lits; r++) {
        replacement = *r;
        assert (VALID_INTERNAL_LITERAL (replacement));
        replacement_value = values[replacement];
        if (replacement_value >= 0)
          break;
      }
      if (replacement_value < 0) {
        for (r = lits + 2; r != searched; r++) {
          replacement = *r;
          assert (VALID_INTERNAL_LITERAL (replacement));
          replacement_value = values[replacement];
          if (replacement_value >= 0)
            break;
        }
      }

      if (replacement_value >= 0) {
        c->searched = r - lits;
        assert (replacement != INVALID_LIT);
        LOGREF3 (ref, "unwatching %s in", LOGLIT (not_lit));
        q -= 2;
        lits[0] = other;
        lits[1] = replacement;
        assert (lits[0] != lits[1]);
        *r = not_lit;
        kissat_delay_watching_large (solver, delayed, replacement, other,
                                     ref);
        ticks++;
      } else if (other_value) {
        assert (replacement_value < 0);
        assert (blocking_value < 0);
        assert (other_value < 0);
#if defined(PROBING_PROPAGATION)
        if (c == ignore) {
          LOGREF (ref, "conflicting but ignored");
          continue;
        }
#endif
        LOGREF (ref, "conflicting");
        res = c;
#ifndef CONTINUE_PROPAGATING_AFTER_CONFLICT
        break;
#endif
      } else {
        assert (replacement_value < 0);
#if defined(PROBING_PROPAGATION)
        if (c == ignore) {
          LOGREF (ref, "forcing %s but ignored", LOGLIT (other));
          continue;
        }
#endif
        kissat_fast_assign_reference (solver, values, assigned, other, ref,
                                      c);
        ticks++;
      }
    }
  }
  solver->ticks += ticks;

  while (p != end_watches)
    *q++ = *p++;
  SET_END_OF_WATCHES (*watches, q);

  kissat_watch_large_delayed (solver, all_watches, delayed);

  return res;
}

 

//fastassign.h

static inline void kissat_fast_binary_assign (
    kissat *solver, const bool probing, const unsigned level, value *values,
    assigned *assigned, unsigned lit, unsigned other) {
  if (GET_OPTION (jumpreasons) && level && solver->classification.bigbig) {
    unsigned other_idx = IDX (other);
    struct assigned *a = assigned + other_idx;
    if (a->binary) {
      LOGBINARY (lit, other, "jumping %s reason", LOGLIT (lit));
      INC (jumped_reasons);
      other = a->reason;
    }
  }
  kissat_fast_assign (solver, probing, level, values, assigned, true, lit,
                      other);
  LOGBINARY (lit, other, "assign %s reason", LOGLIT (lit));
}

static inline void
kissat_fast_assign_reference (kissat *solver, value *values,
                              assigned *assigned, unsigned lit,
                              reference ref, clause *reason) {
  assert (reason == kissat_dereference_clause (solver, ref));
  const unsigned level =
      kissat_assignment_level (solver, values, assigned, lit, reason);
  assert (level <= solver->level);
  assert (ref != DECISION_REASON);
  assert (ref != UNIT_REASON);
  kissat_fast_assign (solver, solver->probing, level, values, assigned,
                      false, lit, ref);
  LOGREF (ref, "assign %s reason", LOGLIT (lit));
}

 

最总落实到函数

#ifdef FAST_ASSIGN
#define kissat_assign kissat_fast_assign
#endif

static inline void kissat_assign (kissat *solver, const bool probing,
                                  const unsigned level,
#ifdef FAST_ASSIGN
                                  value *values, assigned *assigned,
#endif
                                  bool binary, unsigned lit,
                                  unsigned reason) {
  const unsigned not_lit = NOT (lit);

  watches watches = WATCHES (not_lit);
  if (!kissat_empty_vector (&watches)) {
    watch *w = BEGIN_WATCHES (watches);
    __builtin_prefetch (w, 0, 1);
  }

#ifndef FAST_ASSIGN
  value *values = solver->values;
#endif
  assert (!values[lit]);
  assert (!values[not_lit]);

  values[lit] = 1;
  values[not_lit] = -1;

  assert (solver->unassigned > 0);
  solver->unassigned--;

  if (!level) {
    kissat_mark_fixed_literal (solver, lit);
    assert (solver->unflushed < UINT_MAX);
    solver->unflushed++;
    if (reason != UNIT_REASON) {
      CHECK_AND_ADD_UNIT (lit);
      ADD_UNIT_TO_PROOF (lit);
      reason = UNIT_REASON;
      binary = false;
    }
  }

  const size_t trail = SIZE_ARRAY (solver->trail);
  PUSH_ARRAY (solver->trail, lit);

  const unsigned idx = IDX (lit);

#if !defined(PROBING_PROPAGATION)
  if (!probing) {
    const bool negated = NEGATED (lit);
    const value new_value = BOOL_TO_VALUE (negated);
    value *saved = &SAVED (idx);
    *saved = new_value;
  }
#endif

  struct assigned b;

  b.level = level;
  b.trail = trail;

  b.analyzed = false;
  b.binary = binary;
  b.poisoned = false;
  b.reason = reason;
  b.removable = false;
  b.shrinkable = false;

#ifndef FAST_ASSIGN
  assigned *assigned = solver->assigned;
#endif
  struct assigned *a = assigned + idx;
  *a = b;
}

static inline unsigned
kissat_assignment_level (kissat *solver, value *values, assigned *assigned,
                         unsigned lit, clause *reason) {
  unsigned res = 0;
  for (all_literals_in_clause (other, reason)) {
    if (other == lit)
      continue;
    assert (values[other] < 0), (void) values;
    const unsigned other_idx = IDX (other);
    struct assigned *a = assigned + other_idx;
    const unsigned level = a->level;
    if (res < level)
      res = level;
  }
#ifdef NDEBUG
  (void) solver;
#endif
  return res;
}

 

由于BCP是用时最多的模块,单独将与传播有关inline函数保存在一个文件中,见inline.h

inline.h

 

   

 

 

 

4.智能回退模块

 

5.重启机制模块

 

 //触发重启的判别

//restart.c

bool kissat_restarting (kissat *solver) {
  assert (solver->unassigned);
  if (!GET_OPTION (restart))
    return false;
  if (!solver->level)
    return false;
  if (CONFLICTS < solver->limits.restart.conflicts)
    return false;
  if (solver->stable)
    return kissat_reluctant_triggered (&solver->reluctant);
  const double fast = AVERAGE (fast_glue);
  const double slow = AVERAGE (slow_glue);
  const double margin = (100.0 + GET_OPTION (restartmargin)) / 100.0;
  const double limit = margin * slow;
  kissat_extremely_verbose (solver,
                            "restart glue limit %g = "
                            "%.02f * %g (slow glue) %c %g (fast glue)",
                            limit, margin, slow,
                            (limit > fast    ? '>'
                             : limit == fast ? '='
                                             : '<'),
                            fast);
  return (limit <= fast);
}

 

 

//重启的策略

(1)CONFLICTS  <  solver->limits.restart.conflicts

     limit的更新在前一次重启实现时进行更新;

(2)reluctant.h中定义的reluctant_triggered触发

kissat_reluctant_triggered (&solver->reluctant);

 1 #ifndef _reluctant_h_INCLUDED
 2 #define _reluctant_h_INCLUDED
 3 
 4 #include <stdbool.h>
 5 #include <stdint.h>
 6 
 7 typedef struct reluctant reluctant;
 8 
 9 struct reluctant {
10   bool limited;
11   bool trigger;
12   uint64_t period;
13   uint64_t wait;
14   uint64_t u, v;
15   uint64_t limit;
16 };
17 
18 void kissat_enable_reluctant (reluctant *, uint64_t period, uint64_t limit);
19 void kissat_disable_reluctant (reluctant *);
20 void kissat_tick_reluctant (reluctant *);
21 
22 static inline bool kissat_reluctant_triggered (reluctant *reluctant) {
23   if (!reluctant->trigger)
24     return false;
25   reluctant->trigger = false;
26   return true;
27 }
28 
29 struct kissat;
30 
31 void kissat_init_reluctant (struct kissat *);
32 
33 #endif
reluctant.h
 1 #include "internal.h"
 2 #include "logging.h"
 3 
 4 void kissat_enable_reluctant (reluctant *reluctant, uint64_t period,
 5                               uint64_t limit) {
 6   if (limit && period > limit)
 7     period = limit;
 8   reluctant->limited = (limit > 0);
 9   reluctant->trigger = false;
10   reluctant->period = period;
11   reluctant->wait = period;
12   reluctant->u = reluctant->v = 1;
13   reluctant->limit = limit;
14 }
15 
16 void kissat_disable_reluctant (reluctant *reluctant) {
17   reluctant->period = 0;
18 }
19 
20 void kissat_tick_reluctant (reluctant *reluctant) {
21   if (!reluctant->period)
22     return;
23 
24   if (reluctant->trigger)
25     return;
26 
27   assert (reluctant->wait > 0);
28   if (--reluctant->wait)
29     return;
30 
31   uint64_t u = reluctant->u;
32   uint64_t v = reluctant->v;
33 
34   if ((u & -u) == v) {
35     u++;
36     v = 1;
37   } else {
38     assert (UINT64_MAX / 2 >= v);
39     v *= 2;
40   }
41 
42   assert (v);
43   assert (UINT64_MAX / v >= reluctant->period);
44   uint64_t wait = v * reluctant->period;
45 
46   if (reluctant->limited && wait > reluctant->limit) {
47     u = v = 1;
48     wait = reluctant->period;
49   }
50 
51   reluctant->trigger = true;
52   reluctant->wait = wait;
53   reluctant->u = u;
54   reluctant->v = v;
55 }
56 
57 void kissat_init_reluctant (kissat *solver) {
58   if (GET_OPTION (reluctant)) {
59     LOG ("enable reluctant doubling with period %d limit %d",
60          GET_OPTION (reluctantint), GET_OPTION (reluctantlim));
61     kissat_enable_reluctant (&solver->reluctant, GET_OPTION (reluctantint),
62                              GET_OPTION (reluctantlim));
63   } else {
64     LOG ("reluctant doubling disabled and thus no stable restarts");
65     kissat_disable_reluctant (&solver->reluctant);
66   }
67 }
reluctant.c


  (3) 学习子句LBD值移动平均的短期和长期的模型

   见上述代码的部分:最下部分   由(limit <= fast)确定是否触发。

 

 

 

//重启都干了什么?

  (1)unsigned level = reuse_trail (solver);

  (2)kissat_backtrack_in_consistent_state (solver, level);

  (3)关于下次重启界限的更新

  if (!solver->stable)
    kissat_update_focused_restart_limit (solver);

//先看关于下次重启界限的更新

//restart.c

void kissat_update_focused_restart_limit (kissat *solver) {
  assert (!solver->stable);
  limits *limits = &solver->limits;
  uint64_t restarts = solver->statistics.restarts;
  uint64_t delta = GET_OPTION (restartint);
  if (restarts)
    delta += kissat_logn (restarts) - 1;
  limits->restart.conflicts = CONFLICTS + delta;
  kissat_extremely_verbose (solver,
                            "focused restart limit at %" PRIu64
                            " after %" PRIu64 " conflicts ",
                            limits->restart.conflicts, delta);
}

//回溯到0还是复用一部分

 1 static unsigned reuse_stable_trail (kissat *solver) {
 2   const heap *const scores = SCORES;
 3   const unsigned next_idx = kissat_next_decision_variable (solver);
 4   const double limit = kissat_get_heap_score (scores, next_idx);
 5   unsigned level = solver->level, res = 0;
 6   while (res < level) {
 7     frame *f = &FRAME (res + 1);
 8     const unsigned idx = IDX (f->decision);
 9     const double score = kissat_get_heap_score (scores, idx);
10     if (score <= limit)
11       break;
12     res++;
13   }
14   return res;
15 }
16 
17 static unsigned reuse_focused_trail (kissat *solver) {
18   const links *const links = solver->links;
19   const unsigned next_idx = kissat_next_decision_variable (solver);
20   const unsigned limit = links[next_idx].stamp;
21   LOG ("next decision variable stamp %u", limit);
22   unsigned level = solver->level, res = 0;
23   while (res < level) {
24     frame *f = &FRAME (res + 1);
25     const unsigned idx = IDX (f->decision);
26     const unsigned score = links[idx].stamp;
27     if (score <= limit)
28       break;
29     res++;
30   }
31   return res;
32 }
33 
34 static unsigned reuse_trail (kissat *solver) {
35   assert (solver->level);
36   assert (!EMPTY_STACK (solver->trail));
37 
38   if (!GET_OPTION (restartreusetrail))
39     return 0;
40 
41   unsigned res;
42 
43   if (solver->stable)
44     res = reuse_stable_trail (solver);
45   else
46     res = reuse_focused_trail (solver);
47 
48   LOG ("matching trail level %u", res);
49 
50   if (res) {
51     INC (restarts_reused_trails);
52     ADD (restarts_reused_levels, res);
53     LOG ("restart reuses trail at decision level %u", res);
54   } else
55     LOG ("restarts does not reuse the trail");
56 
57   return res;
58 }
获取reuse的层位置

 

//回溯的实施

 1 //restart.c
 2 
 3 void kissat_restart (kissat *solver) {
 4   START (restart);
 5   INC (restarts);
 6   ADD (restarts_levels, solver->level);
 7   if (solver->stable)
 8     INC (stable_restarts);
 9   else
10     INC (focused_restarts);
11 
12 
13   unsigned level = reuse_trail (solver); 
14   kissat_extremely_verbose (solver,
15                             "restarting after %" PRIu64 " conflicts"
16                             " (limit %" PRIu64 ")",
17                             CONFLICTS, solver->limits.restart.conflicts);
18   LOG ("restarting to level %u", level);
19   kissat_backtrack_in_consistent_state (solver, level);
20 
21   
22   if (!solver->stable)
23     kissat_update_focused_restart_limit (solver);
24   REPORT (1, 'R');
25   STOP (restart);
26 }

 

 //backtrack.h

1
#ifndef _backtrack_h_INCLUDED 2 #define _backtrack_h_INCLUDED 3 4 struct kissat; 5 6 void kissat_backtrack_without_updating_phases (struct kissat *, unsigned); 7 void kissat_backtrack_in_consistent_state (struct kissat *, unsigned); 8 void kissat_backtrack_after_conflict (struct kissat *, unsigned); 9 void kissat_backtrack_propagate_and_flush_trail (struct kissat *); 10 11 #endif
 1 //backtrack.c
 2 
 3 void kissat_backtrack_without_updating_phases (kissat *solver,
 4                                                unsigned new_level) {
 5   assert (solver->level >= new_level);
 6   if (solver->level == new_level)
 7     return;
 8 
 9   LOG ("backtracking to decision level %u", new_level);
10 
11   frame *new_frame = &FRAME (new_level + 1);
12   SET_END_OF_STACK (solver->frames, new_frame);
13 
14   value *values = solver->values;
15   unsigned *trail = BEGIN_ARRAY (solver->trail);
16   unsigned *new_end = trail + new_frame->trail;
17   assigned *assigned = solver->assigned;
18 
19   unsigned *old_end = END_ARRAY (solver->trail);
20   unsigned unassigned = 0, reassigned = 0;
21 
22   unsigned *q = new_end;
23   if (solver->stable) {
24     heap *scores = SCORES;
25     for (const unsigned *p = q; p != old_end; p++) {
26       const unsigned lit = *p;
27       const unsigned idx = IDX (lit);
28       assert (idx < VARS);
29       struct assigned *a = assigned + idx;
30       const unsigned level = a->level;
31       if (level <= new_level) {
32         const unsigned new_trail = q - trail;
33         assert (new_trail <= a->trail);
34         a->trail = new_trail;
35         *q++ = lit;
36         LOG ("reassign %s", LOGLIT (lit));
37         reassigned++;
38       } else {
39         unassign (solver, values, lit);
40         add_unassigned_variable_back_to_heap (solver, scores, lit);
41         unassigned++;
42       }
43     }
44   } else {
45     links *links = solver->links;
46     for (const unsigned *p = q; p != old_end; p++) {
47       const unsigned lit = *p;
48       const unsigned idx = IDX (lit);
49       assert (idx < VARS);
50       struct assigned *a = assigned + idx;
51       const unsigned level = a->level;
52       if (level <= new_level) {
53         const unsigned new_trail = q - trail;
54         assert (new_trail <= a->trail);
55         a->trail = new_trail;
56         *q++ = lit;
57         LOG ("reassign %s", LOGLIT (lit));
58         reassigned++;
59       } else {
60         unassign (solver, values, lit);
61         add_unassigned_variable_back_to_queue (solver, links, lit);
62         unassigned++;
63       }
64     }
65   }
66   SET_END_OF_ARRAY (solver->trail, q);
67 
68   solver->level = new_level;
69   LOG ("unassigned %u literals", unassigned);
70   LOG ("reassigned %u literals", reassigned);
71   (void) unassigned, (void) reassigned;
72 
73   assert (new_end <= END_ARRAY (solver->trail));
74   LOG ("propagation will resume at trail position %zu",
75        (size_t) (new_end - trail));
76   solver->propagate = new_end;
77 
78   assert (!solver->extended);
79 }

 

  1 #include "backtrack.h"
  2 #include "analyze.h"
  3 #include "inline.h"
  4 #include "inlineheap.h"
  5 #include "inlinequeue.h"
  6 #include "print.h"
  7 #include "proprobe.h"
  8 #include "propsearch.h"
  9 #include "trail.h"
 10 
 11 static inline void unassign (kissat *solver, value *values, unsigned lit) {
 12   LOG ("unassign %s", LOGLIT (lit));
 13   assert (values[lit] > 0);
 14   const unsigned not_lit = NOT (lit);
 15   values[lit] = values[not_lit] = 0;
 16   assert (solver->unassigned < VARS);
 17   solver->unassigned++;
 18 }
 19 
 20 static inline void add_unassigned_variable_back_to_queue (kissat *solver,
 21                                                           links *links,
 22                                                           unsigned lit) {
 23   assert (!solver->stable);
 24   const unsigned idx = IDX (lit);
 25   if (links[idx].stamp > solver->queue.search.stamp)
 26     kissat_update_queue (solver, links, idx);
 27 }
 28 
 29 static inline void add_unassigned_variable_back_to_heap (kissat *solver,
 30                                                          heap *scores,
 31                                                          unsigned lit) {
 32   assert (solver->stable);
 33   const unsigned idx = IDX (lit);
 34   if (!kissat_heap_contains (scores, idx))
 35     kissat_push_heap (solver, scores, idx);
 36 }
 37 
 38 static void kissat_update_target_and_best_phases (kissat *solver) {
 39   if (solver->probing)
 40     return;
 41 
 42   if (!solver->stable)
 43     return;
 44 
 45   const unsigned assigned = kissat_assigned (solver);
 46 #ifdef LOGGING
 47   LOG ("updating target and best phases");
 48   LOG ("currently %u variables assigned", assigned);
 49 #endif
 50 
 51   if (solver->target_assigned < assigned) {
 52     kissat_extremely_verbose (solver,
 53                               "updating target assigned "
 54                               "trail height from %u to %u",
 55                               solver->target_assigned, assigned);
 56     solver->target_assigned = assigned;
 57     kissat_save_target_phases (solver);
 58     INC (target_saved);
 59   }
 60 
 61   if (solver->best_assigned < assigned) {
 62     kissat_extremely_verbose (solver,
 63                               "updating best assigned "
 64                               "trail height from %u to %u",
 65                               solver->best_assigned, assigned);
 66     solver->best_assigned = assigned;
 67     kissat_save_best_phases (solver);
 68     INC (best_saved);
 69   }
 70 }
 71 
 72 void kissat_backtrack_without_updating_phases (kissat *solver,
 73                                                unsigned new_level) {
 74   assert (solver->level >= new_level);
 75   if (solver->level == new_level)
 76     return;
 77 
 78   LOG ("backtracking to decision level %u", new_level);
 79 
 80   frame *new_frame = &FRAME (new_level + 1);
 81   SET_END_OF_STACK (solver->frames, new_frame);
 82 
 83   value *values = solver->values;
 84   unsigned *trail = BEGIN_ARRAY (solver->trail);
 85   unsigned *new_end = trail + new_frame->trail;
 86   assigned *assigned = solver->assigned;
 87 
 88   unsigned *old_end = END_ARRAY (solver->trail);
 89   unsigned unassigned = 0, reassigned = 0;
 90 
 91   unsigned *q = new_end;
 92   if (solver->stable) {
 93     heap *scores = SCORES;
 94     for (const unsigned *p = q; p != old_end; p++) {
 95       const unsigned lit = *p;
 96       const unsigned idx = IDX (lit);
 97       assert (idx < VARS);
 98       struct assigned *a = assigned + idx;
 99       const unsigned level = a->level;
100       if (level <= new_level) {
101         const unsigned new_trail = q - trail;
102         assert (new_trail <= a->trail);
103         a->trail = new_trail;
104         *q++ = lit;
105         LOG ("reassign %s", LOGLIT (lit));
106         reassigned++;
107       } else {
108         unassign (solver, values, lit);
109         add_unassigned_variable_back_to_heap (solver, scores, lit);
110         unassigned++;
111       }
112     }
113   } else {
114     links *links = solver->links;
115     for (const unsigned *p = q; p != old_end; p++) {
116       const unsigned lit = *p;
117       const unsigned idx = IDX (lit);
118       assert (idx < VARS);
119       struct assigned *a = assigned + idx;
120       const unsigned level = a->level;
121       if (level <= new_level) {
122         const unsigned new_trail = q - trail;
123         assert (new_trail <= a->trail);
124         a->trail = new_trail;
125         *q++ = lit;
126         LOG ("reassign %s", LOGLIT (lit));
127         reassigned++;
128       } else {
129         unassign (solver, values, lit);
130         add_unassigned_variable_back_to_queue (solver, links, lit);
131         unassigned++;
132       }
133     }
134   }
135   SET_END_OF_ARRAY (solver->trail, q);
136 
137   solver->level = new_level;
138   LOG ("unassigned %u literals", unassigned);
139   LOG ("reassigned %u literals", reassigned);
140   (void) unassigned, (void) reassigned;
141 
142   assert (new_end <= END_ARRAY (solver->trail));
143   LOG ("propagation will resume at trail position %zu",
144        (size_t) (new_end - trail));
145   solver->propagate = new_end;
146 
147   assert (!solver->extended);
148 }
149 
150 void kissat_backtrack_in_consistent_state (kissat *solver,
151                                            unsigned new_level) {
152   kissat_update_target_and_best_phases (solver);
153   kissat_backtrack_without_updating_phases (solver, new_level);
154 }
155 
156 void kissat_backtrack_after_conflict (kissat *solver, unsigned new_level) {
157   if (solver->level)
158     kissat_backtrack_without_updating_phases (solver, solver->level - 1);
159   kissat_update_target_and_best_phases (solver);
160   kissat_backtrack_without_updating_phases (solver, new_level);
161 }
162 
163 void kissat_backtrack_propagate_and_flush_trail (kissat *solver) {
164   if (solver->level) {
165     assert (solver->watching);
166     kissat_backtrack_in_consistent_state (solver, 0);
167 #ifndef NDEBUG
168     clause *conflict =
169 #endif
170         solver->probing ? kissat_probing_propagate (solver, 0, true)
171                         : kissat_search_propagate (solver);
172     assert (!conflict);
173   }
174 
175   assert (kissat_propagated (solver));
176   assert (kissat_trail_flushed (solver));
177 }
完整的backtrack.c代码

 

 

 

   

 6.冲突分析模块

 

// 冲突分析的主代码段

 1 int kissat_analyze (kissat *solver, clause *conflict) {
 2   if (solver->inconsistent) {
 3     assert (!solver->level);
 4     return 20;
 5   }
 6 
 7   START (analyze);
 8   if (!solver->probing) {
 9     update_trail_average (solver);
10     update_decision_rate_average (solver);
11 #ifndef QUIET
12     UPDATE_AVERAGE (level, solver->level);
13 #endif
14   }
15   int res;
16   do {
17     LOGCLS (conflict, "analyzing conflict %" PRIu64, CONFLICTS);
18     unsigned conflict_level;
19     if (one_literal_on_conflict_level (solver, conflict, &conflict_level))
20       res = 1;
21     else if (!conflict_level)
22       res = -1;
23     else if (conflict_level == 1) {
24       analyze_failed_literal (solver, conflict);
25       res = 1;
26     } else if ((conflict =
27                     kissat_deduce_first_uip_clause (solver, conflict))) {
28       reset_analysis_but_not_analyzed_literals (solver);
29       INC (conflicts);
30       if (CONFLICTS > solver->limits.glue.conflicts)
31         update_tier_limits (solver);
32       res = 0; // And continue with new conflict analysis.
33     } else {
34       if (GET_OPTION (minimize)) {
35         sort_deduced_clause (solver);
36         kissat_minimize_clause (solver);
37         if (GET_OPTION (shrink))
38           kissat_shrink_clause (solver);
39       }
40       analyze_reason_side_literals (solver);
41       kissat_learn_clause (solver);
42       reset_analysis_but_not_analyzed_literals (solver);
43       res = 1;
44     }
45     if (!EMPTY_STACK (solver->analyzed)) {
46       if (!solver->probing && GET_OPTION (bump))
47         kissat_bump_analyzed (solver);
48       kissat_reset_only_analyzed_literals (solver);
49     }
50   } while (!res);
51   STOP (analyze);
52   return res > 0 ? 0 : 20;
53 }

//分5部分理解。其中第四第五可以连起来分析。

 

 

// 红色标出的循环体,主要目的是找到1-UIP,其中需要记录的信息可以从两个清除函数了解:

  reset_analysis_but_not_analyzed_literals (solver);

  kissat_reset_only_analyzed_literals (solver);

   

7. 子句管理(删除模块)

  //reduce.c
 
//相关数据结构

//
reduce.c typedef struct reducible reducible; struct reducible { uint64_t rank; unsigned ref; }; #define RANK_REDUCIBLE(RED) (RED).rank // clang-format off typedef STACK (reducible) reducibles; // clang-format o

 

 

 

 

//核心函数-排序之后进行拟删除子句的选择。

 

 1 static bool collect_reducibles (kissat *solver, reducibles *reds,
 2                                 reference start_ref) {
 3   assert (start_ref != INVALID_REF);
 4   assert (start_ref <= SIZE_STACK (solver->arena));
 5   ward *const arena = BEGIN_STACK (solver->arena);
 6   clause *start = (clause *) (arena + start_ref);
 7   const clause *const end = (clause *) END_STACK (solver->arena);
 8   assert (start < end);
 9   while (start != end && !start->redundant)
10     start = kissat_next_clause (start);
11   if (start == end) {
12     solver->first_reducible = INVALID_REF;
13     LOG ("no reducible clause candidate left");
14     return false;
15   }
16   const reference redundant = (ward *) start - arena;
17 #ifdef LOGGING
18   if (redundant < solver->first_reducible)
19     LOG ("updating start of redundant clauses from %zu to %zu",
20          (size_t) solver->first_reducible, (size_t) redundant);
21   else
22     LOG ("no update to start of redundant clauses %zu",
23          (size_t) solver->first_reducible);
24 #endif
25   solver->first_reducible = redundant;
26   const unsigned tier1 = TIER1;
27   const unsigned tier2 = MAX (tier1, TIER2);
28   assert (tier1 <= tier2);
29   for (clause *c = start; c != end; c = kissat_next_clause (c)) {
30     if (!c->redundant)
31       continue;
32     if (c->garbage)
33       continue;
34     const unsigned used = c->used;
35     if (used)
36       c->used = used - 1;
37     if (c->reason)
38       continue;
39     const unsigned glue = c->glue;
40     if (glue <= tier1 && used)
41       continue;
42     if (glue <= tier2 && used >= MAX_USED - 1)
43       continue;
44     assert (kissat_clause_in_arena (solver, c));
45     reducible red;
46     const uint64_t negative_size = ~c->size;
47     const uint64_t negative_glue = ~c->glue;
48     red.rank = negative_size | (negative_glue << 32);
49     red.ref = (ward *) c - arena;
50     PUSH_STACK (*reds, red);
51   }
52   if (EMPTY_STACK (*reds)) {
53     kissat_phase (solver, "reduce", GET (reductions),
54                   "did not find any reducible redundant clause");
55     return false;
56   }
57   return true;
58 }

 

   
   
   
   
   
   
   

 

 

7.预处理模块

 

8.随机搜索模块

9.子求解器kitten模块

10.输入及assume模块

11.学习子句管理模块

12.随机行走模块

13.

 

14. kissat *solver常用数据访问代码整理;

 
  watches *const all_watches = solver->watches;
  ward *const arena = BEGIN_STACK (solver->arena);
  assigned *const assigned = solver->assigned;
  value *const values = solver->values;

  const unsigned not_lit = NOT (lit);

 

//已知观察元cur_watcher,获取该观察元所对应子句

  const reference ref = cur_watcher.raw;
  assert (ref < SIZE_STACK (solver->arena));
  clause *const c = (clause *) (arena + ref);

 

 

 

 

 

//常用状态或进度指示量

//
solver->inconsistent = true;  //出现UNSAT情况

//
const bool probing = solver->probing;

//
solver->level
// solver->watching
// solver->iterating

//
solver->extended

// solver->stable // limits *limits = &solver->limits; limited *limited = &solver->limited; if (!limited->conflicts && !limited->decisions) kissat_very_verbose (solver, "starting unlimited search"); // static void init_tiers (kissat *solver) { for (unsigned stable = 0; stable != 2; stable++) { if (!solver->tier1[stable]) { assert (!solver->tier2[stable]); solver->tier1[stable] = GET_OPTION (tier1); solver->tier2[stable] = GET_OPTION (tier2); if (solver->tier2[stable] <= solver->tier1[stable]) solver->tier2[stable] = solver->tier1[stable]; LOG ("initialized tier1[%u] glue to %u", stable, solver->tier1[stable]); LOG ("initialized tier2[%u] glue to %u", stable, solver->tier2[stable]); if (!solver->limits.glue.interval) solver->limits.glue.interval = 2; } } }


//

void kissat_set_conflict_limit (kissat *solver, unsigned limit) {

kissat_require_initialized (solver);
limits *limits = &solver->limits;
limited *limited = &solver->limited;
statistics *statistics = &solver->statistics;
limited->conflicts = true;
assert (UINT64_MAX - limit >= statistics->conflicts);
limits->conflicts = statistics->conflicts + limit;
LOG ("set conflict limit to %" PRIu64 " after %u conflicts",
limits->conflicts, limit);

  }

//
unsigned seed = GET_OPTION (seed);
solver->random = seed;
LOG ("initialized random number generator with seed %u", seed);

//
unsigned *trail = BEGIN_ARRAY (solver->trail);

// LOG ("backtracking to decision level %u", new_level);

  // frame *new_frame = &FRAME (new_level + 1);
  // SET_END_OF_STACK (solver->frames, new_frame);
  // unsigned *new_end = trail + new_frame->trail;



//
solver->conflict

//
solver->clause

//
solver->clause_trivial

//
solver->clause_shrink

//
solver->original

//
solver->clause_satisfied

//
solver->offset_of_last_original_clause

//
solver->shadow

//
solver->removable

//
solver->compacting






//
solver->vars
//
solver->scores

//
solver->queue

//
solver->unassigned
//
solver->last_learned



//
solver->propagate


//
solver->links

//
solver->analyzed

//
solver->ranks



//

static void dump_queue (kissat *solver) {
  const queue *const queue = &solver->queue;
  printf ("queue: first %u, last %u, stamp %u, search %u (stamp %u)\n",
  queue->first, queue->last, queue->stamp, queue->search.idx,
  queue->search.stamp);
  const links *const links = solver->links;
  for (unsigned idx = queue->first; !DISCONNECTED (idx);
    idx = links[idx].next) {
    const struct links *l = links + idx;
    printf ("%u ( prev %u, next %u, stamp %u )\n", idx, l->prev, l->next,l->stamp);
  }
}

//


 

void dump_map (kissat *solver) {
  const unsigned size = SIZE_STACK (solver->export);
  unsigned first = INVALID_LIT;
  for (unsigned idx = 0; idx < size; idx++) {
    const unsigned ilit = LIT (idx);
    const int elit = PEEK_STACK (solver->export, idx);
    printf ("map[%u] -> %d", ilit, elit);
    if (elit) {
      const unsigned eidx = ABS (elit);
      const import *const import = &PEEK_STACK (solver->import, eidx);
      if (import->eliminated)
        printf (" -> eliminated[%u]", import->lit);
      else {
        unsigned mlit = import->lit;
        if (elit < 0)
          mlit = NOT (mlit);
        printf (" -> %u", mlit);
      }
    }
    if (!LEVEL (ilit) && VALUE (ilit)) {
      if (first == INVALID_LIT) {
        first = ilit;
        printf (" #");
      } else
        printf (" *");
    }
    fputc ('\n', stdout);
  }
}

 

 

   
posted on 2024-09-18 09:58  海阔凭鱼跃越  阅读(14)  评论(0编辑  收藏  举报