ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
learn.c
Go to the documentation of this file.
1#include "learn.h"
2#include "backtrack.h"
3#include "inline.h"
4#include "reluctant.h"
5
6#include <inttypes.h>
7
9
10static unsigned backjump_limit (struct kissat *solver) {
11#ifdef KISSAT_NOPTIONS
12 (void) solver;
13#endif
14 return GET_OPTION (chrono) ? (unsigned) GET_OPTION (chronolevels)
15 : UINT_MAX;
16}
17
18unsigned kissat_determine_new_level (kissat *solver, unsigned jump) {
19 KISSAT_assert (solver->level);
20 const unsigned back = solver->level - 1;
21 KISSAT_assert (jump <= back);
22
23 const unsigned delta = back - jump;
24 const unsigned limit = backjump_limit (solver);
25
26 unsigned res;
27
28 if (!delta) {
29 res = jump;
30 LOG ("using identical backtrack and jump level %u", res);
31 } else if (delta > limit) {
32 res = back;
33 LOG ("backjumping over %u levels (%u - %u) considered inefficient",
34 delta, back, jump);
35 LOG ("backtracking chronologically to backtrack level %u", res);
36 INC (chronological);
37 } else {
38 res = jump;
39 LOG ("backjumping over %u levels (%u - %u) considered efficient", delta,
40 back, jump);
41 LOG ("backjumping non-chronologically to jump level %u", res);
42 }
43 return res;
44}
45
46static void learn_unit (kissat *solver, unsigned not_uip) {
47 KISSAT_assert (not_uip == PEEK_STACK (solver->clause, 0));
48 LOG ("learned unit clause %s triggers iteration", LOGLIT (not_uip));
49 const unsigned new_level = kissat_determine_new_level (solver, 0);
51 kissat_learned_unit (solver, not_uip);
52 if (!solver->probing) {
53 solver->iterating = true;
54 INC (iterations);
55 }
56}
57
58static void learn_binary (kissat *solver, unsigned not_uip) {
59 const unsigned other = PEEK_STACK (solver->clause, 1);
60 const unsigned jump_level = LEVEL (other);
61 const unsigned new_level =
64#ifndef KISSAT_NDEBUG
65 const reference ref =
66#endif
69 kissat_assign_binary (solver, not_uip, other);
70}
71
72static void insert_last_learned (kissat *solver, reference ref) {
73 const reference *const end =
74 solver->last_learned + GET_OPTION (eagersubsume);
75 reference prev = ref;
76 for (reference *p = solver->last_learned; p != end; p++) {
77 reference tmp = *p;
78 *p = prev;
79 prev = tmp;
80 }
81}
82
83static reference learn_reference (kissat *solver, unsigned not_uip,
84 unsigned glue) {
85 KISSAT_assert (solver->level > 1);
86 KISSAT_assert (SIZE_STACK (solver->clause) > 2);
87 unsigned *lits = BEGIN_STACK (solver->clause);
88 KISSAT_assert (lits[0] == not_uip);
89 unsigned *q = lits + 1;
90 unsigned jump_lit = *q;
91 unsigned jump_level = LEVEL (jump_lit);
92 const unsigned *const end = END_STACK (solver->clause);
93 const unsigned backtrack_level = solver->level - 1;
94 assigned *all_assigned = solver->assigned;
95 for (unsigned *p = lits + 2; p != end; p++) {
96 const unsigned lit = *p;
97 const unsigned idx = IDX (lit);
98 const unsigned level = all_assigned[idx].level;
99 if (jump_level >= level)
100 continue;
101 jump_level = level;
102 jump_lit = lit;
103 q = p;
104 if (level == backtrack_level)
105 break;
106 }
107 *q = lits[1];
108 lits[1] = jump_lit;
110 KISSAT_assert (ref != INVALID_REF);
111 clause *c = kissat_dereference_clause (solver, ref);
112 c->used = MAX_USED;
113 const unsigned new_level =
116 kissat_assign_reference (solver, not_uip, ref, c);
117 return ref;
118}
119
120void kissat_update_learned (kissat *solver, unsigned glue, unsigned size) {
121 KISSAT_assert (!solver->probing);
122 INC (clauses_learned);
123 LOG ("learned[%" PRIu64 "] clause glue %u size %u", GET (clauses_learned),
124 glue, size);
125 if (solver->stable)
126 kissat_tick_reluctant (&solver->reluctant);
127 ADD (literals_learned, size);
128#ifndef KISSAT_QUIET
129 UPDATE_AVERAGE (size, size);
130#endif
131 UPDATE_AVERAGE (fast_glue, glue);
132 UPDATE_AVERAGE (slow_glue, glue);
133}
134
135static void flush_last_learned (kissat *solver) {
136 reference *q = solver->last_learned;
137 const reference *const end = q + GET_OPTION (eagersubsume), *p = q;
138 while (p != end) {
139 reference ref = *p++;
140 if (ref != INVALID_REF)
141 *q++ = ref;
142 }
143 while (q != end)
144 *q++ = INVALID_REF;
145}
146
147static void eagerly_subsume_last_learned (kissat *solver) {
148 value *marks = solver->marks;
149 for (all_stack (unsigned, lit, solver->clause)) {
150 KISSAT_assert (!marks[lit]);
151 marks[lit] = 1;
152 }
153 unsigned clause_size = SIZE_STACK (solver->clause);
154 unsigned subsumed = 0;
155 reference *p = solver->last_learned;
156 const reference *const end = p + GET_OPTION (eagersubsume);
157 while (p != end) {
158 reference ref = *p++;
159 if (ref == INVALID_REF)
160 continue;
161 clause *c = kissat_dereference_clause (solver, ref);
162 if (c->garbage)
163 continue;
164 if (!c->redundant)
165 continue;
166 unsigned c_size = c->size;
167 if (c_size <= clause_size)
168 continue;
169 LOGCLS2 (c, "trying to eagerly subsume");
170 unsigned needed = clause_size;
171 unsigned remain = c_size;
172 for (all_literals_in_clause (lit, c)) {
173 if (marks[lit] && !--needed)
174 break;
175 else if (--remain < needed)
176 break;
177 }
178 if (needed)
179 continue;
180 LOGCLS (c, "eagerly subsumed");
182 p[-1] = INVALID_REF;
183 subsumed++;
184 INC (eagerly_subsumed);
185 }
186 for (all_stack (unsigned, lit, solver->clause))
187 marks[lit] = 0;
188 if (subsumed)
189 flush_last_learned (solver);
190}
191
193 const unsigned not_uip = PEEK_STACK (solver->clause, 0);
194 const unsigned size = SIZE_STACK (solver->clause);
195 const size_t glue = SIZE_STACK (solver->levels);
196 KISSAT_assert (glue <= UINT_MAX);
197 if (!solver->probing)
198 kissat_update_learned (solver, glue, size);
199 KISSAT_assert (size > 0);
201 if (size == 1)
202 learn_unit (solver, not_uip);
203 else if (size == 2)
204 learn_binary (solver, not_uip);
205 else
206 ref = learn_reference (solver, not_uip, glue);
207 if (GET_OPTION (eagersubsume)) {
208 eagerly_subsume_last_learned (solver);
209 if (ref != INVALID_REF)
210 insert_last_learned (solver, ref);
211 }
212}
213
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
void kissat_learned_unit(kissat *solver, unsigned lit)
Definition assign.c:18
void kissat_assign_binary(kissat *solver, unsigned lit, unsigned other)
Definition assign.c:34
void kissat_assign_reference(kissat *solver, unsigned lit, reference ref, clause *reason)
Definition assign.c:49
#define LEVEL(LIT)
Definition assign.h:34
void kissat_backtrack_after_conflict(kissat *solver, unsigned new_level)
Definition backtrack.c:158
#define BEGIN_STACK(S)
Definition stack.h:46
#define all_stack(T, E, S)
Definition stack.h:94
#define SIZE_STACK(S)
Definition stack.h:19
#define PEEK_STACK(S, N)
Definition stack.h:29
#define END_STACK(S)
Definition stack.h:48
#define ADD(NAME, DELTA)
#define INC(NAME)
#define LOG(...)
ABC_NAMESPACE_IMPL_START typedef signed char value
reference kissat_new_redundant_clause(kissat *solver, unsigned glue)
Definition clause.c:146
void kissat_mark_clause_as_garbage(kissat *solver, clause *c)
Definition clause.c:164
#define UPDATE_AVERAGE(A, Y)
Definition ema.hpp:56
Cube * p
Definition exorList.c:222
#define MAX_USED
Definition clause.h:20
#define all_literals_in_clause(LIT, C)
Definition clause.h:47
#define KISSAT_assert(ignore)
Definition global.h:13
#define solver
Definition kitten.c:211
void kissat_learn_clause(kissat *solver)
Definition learn.c:192
unsigned kissat_determine_new_level(kissat *solver, unsigned jump)
Definition learn.c:18
void kissat_update_learned(kissat *solver, unsigned glue, unsigned size)
Definition learn.c:120
#define LOGCLS(...)
Definition logging.h:415
#define LOGCLS2(...)
Definition logging.h:418
#define LOGLIT(...)
Definition logging.hpp:99
unsigned short ref
Definition giaNewBdd.h:38
#define GET_OPTION(N)
Definition options.h:295
#define INVALID_REF
Definition reference.h:16
ABC_NAMESPACE_HEADER_START typedef unsigned reference
Definition reference.h:9
void kissat_tick_reluctant(reluctant *reluctant)
Definition reluctant.c:22
int lit
Definition satVec.h:130
#define IDX(LIT)
Definition literal.h:28
#define GET(NAME)
Definition statistics.h:416
unsigned level
Definition assign.h:19
bool redundant
Definition clause.h:28
unsigned used
Definition clause.h:34
unsigned size
Definition clause.h:37
bool garbage
Definition clause.h:25