ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
cadical_definition.cpp
Go to the documentation of this file.
1#include "global.h"
2
3#include "internal.hpp"
4
6
7namespace CaDiCaL {
8
9#define INVALID_LIT UINT_MAX
10
11// functions below are passed to cadical_kitten
12//
21
22extern "C" {
23
24// used to extract definitions from cadical_kitten
25//
26static void traverse_definition_core (void *state, unsigned id) {
27 definition_extractor *extractor = (definition_extractor *) state;
29 const vector<Clause *> &clauses0 = extractor->clauses[0];
30 const vector<Clause *> &clauses1 = extractor->clauses[1];
31 Eliminator *eliminator = extractor->eliminator;
32 const size_t size_clauses0 = clauses0.size ();
33 const size_t size_clauses1 = clauses1.size ();
34 CADICAL_assert (size_clauses0 <= UINT_MAX);
35 unsigned sign;
36 CADICAL_assert (id < size_clauses0 + size_clauses1);
37 if (id < size_clauses0) {
38 clause = clauses0[id];
39 sign = 1;
40 } else {
41 unsigned tmp = id - size_clauses0;
42#ifndef CADICAL_NDEBUG
43 CADICAL_assert (size_clauses1 <= UINT_MAX);
44 CADICAL_assert (tmp < size_clauses1);
45#endif
46 clause = clauses1[tmp];
47 sign = 2;
48 }
49 (void) size_clauses1;
50 clause->gate = true;
51 eliminator->gates.push_back (clause);
52#ifdef LOGGING
53 Internal *internal = extractor->internal;
54 LOG (clause, "extracted gate");
55#endif
56 eliminator->definition_unit |= sign;
57}
58
59// extracts relevant learned clauses from kissat for drat proofs
60//
61static void traverse_one_sided_core_lemma (void *state, bool learned,
62 size_t size,
63 const unsigned *lits) {
64 if (!learned)
65 return;
66 definition_extractor *extractor = (definition_extractor *) state;
67 Eliminator *eliminator = extractor->eliminator;
68 Internal *internal = extractor->internal;
69 Proof *proof = internal->proof;
70 const int unit = extractor->unit;
71 vector<proof_clause> &proof_clauses = eliminator->proof_clauses;
72 if (size) {
73 proof_clause pc;
74 pc.id = ++(internal->clause_id);
75 pc.literals.push_back (unit);
76 const unsigned *end = lits + size;
77 for (const unsigned *p = lits; p != end; p++)
78 pc.literals.push_back (internal->citten2lit (*p)); // conversion
79 proof_clauses.push_back (pc);
80 CADICAL_assert (proof);
81 proof->add_derived_clause (pc.id, true, pc.literals, pc.chain);
82 } else {
83 internal->assign_unit (unit);
84 for (const auto &pc : proof_clauses) {
85 proof->delete_clause (pc.id, true, pc.literals);
86 }
87 proof_clauses.clear ();
88 }
89}
90
91// extract lrat proofs for relevant clauses
92//
93static void traverse_one_sided_core_lemma_with_lrat (
94 void *state, unsigned cid, unsigned id, bool learned, size_t size,
95 const unsigned *lits, size_t chain_size, const unsigned *chain) {
96 definition_extractor *extractor = (definition_extractor *) state;
97 Eliminator *eliminator = extractor->eliminator;
98 Internal *internal = extractor->internal;
99 Proof *proof = internal->proof;
100 const int unit = extractor->unit;
101 const vector<Clause *> &clauses0 = extractor->clauses[0];
102 const vector<Clause *> &clauses1 = extractor->clauses[1];
103 vector<proof_clause> &proof_clauses = eliminator->proof_clauses;
104 if (!learned) { // remember clauses for mapping to cadical_kitten internal
105 CADICAL_assert (size);
106 CADICAL_assert (!chain_size);
107 proof_clause pc;
108 pc.cid = cid;
109 pc.learned = false;
110 const size_t size_clauses0 = clauses0.size ();
111 CADICAL_assert (size_clauses0 <= UINT_MAX);
112 if (id < size_clauses0) {
113 pc.id = clauses0[id]->id;
114 } else {
115 unsigned tmp = id - size_clauses0;
116#ifndef CADICAL_NDEBUG
117 const size_t size_clauses1 = clauses1.size ();
118 CADICAL_assert (size_clauses1 <= UINT_MAX);
119 CADICAL_assert (tmp < size_clauses1);
120#endif
121 pc.id = clauses1[tmp]->id;
122 }
123 proof_clauses.push_back (pc);
124 } else { // actually add to proof
125 CADICAL_assert (chain_size);
126 if (size) {
127 proof_clause pc;
128 pc.id = ++(internal->clause_id);
129 pc.cid = cid;
130 pc.learned = true;
131 pc.literals.push_back (unit);
132 const unsigned *end = lits + size;
133 for (const unsigned *p = lits; p != end; p++)
134 pc.literals.push_back (internal->citten2lit (*p)); // conversion
135 for (const unsigned *p = chain + chain_size; p != chain; p--) {
136 int64_t id = 0;
137 for (const auto &cpc : proof_clauses) {
138 if (cpc.cid == *(p - 1)) {
139 id = cpc.id;
140 break;
141 }
142 }
143 CADICAL_assert (id);
144 pc.chain.push_back (id);
145 }
146 proof_clauses.push_back (pc);
147 CADICAL_assert (proof);
148 proof->add_derived_clause (pc.id, true, pc.literals, pc.chain);
149 } else { // learn unit finish proof
150 CADICAL_assert (internal->lrat_chain.empty ());
151 for (const unsigned *p = chain + chain_size; p != chain; p--) {
152 int64_t id = 0;
153 for (const auto &cpc : proof_clauses) {
154 if (cpc.cid == *(p - 1)) {
155 id = cpc.id;
156 break;
157 }
158 }
159 CADICAL_assert (id);
160 internal->lrat_chain.push_back (id);
161 }
162 internal->assign_unit (unit);
163 CADICAL_assert (internal->lrat_chain.empty ());
164 for (const auto &pc : proof_clauses) {
165 if (pc.learned)
166 proof->delete_clause (pc.id, true, pc.literals);
167 }
168 proof_clauses.clear ();
169 }
170 }
171}
172
173} // end extern C
174
175// Code ported from kissat. Kitten (and kissat) use unsigned representation
176// for literals whereas CaDiCaL uses signed representation. Conversion is
177// necessary for communication using lit2citten and citten2lit.
178// This code is called in elim and cadical_kitten is initialized beforehand.
179// To avoid confusion all cadical interal definitions with cadical_kitten are called
180// citten.
181//
182void Internal::find_definition (Eliminator &eliminator, int lit) {
183 if (!opts.elimdef)
184 return;
185 if (unsat)
186 return;
187 if (val (lit))
188 return;
189 if (!eliminator.gates.empty ())
190 return;
194 const int not_lit = -lit;
195 definition_extractor extractor;
196 extractor.lit = lit;
197 extractor.clauses[0] = occs (lit);
198 extractor.clauses[1] = occs (not_lit);
199 extractor.eliminator = &eliminator;
200 extractor.internal = internal;
202 unsigned exported = 0;
203 for (unsigned sign = 0; sign < 2; sign++) {
204 const unsigned except = sign ? lit2citten (not_lit) : lit2citten (lit);
205 for (auto c : extractor.clauses[sign]) {
206 // to avoid copying the literals of c in their unsigned
207 // representation we instead implement the translation in cadical_kitten
208 if (!c->garbage) {
209 LOG (c, "adding to cadical_kitten");
211 c->literals, except);
212 }
213 exported++;
214 }
215 }
216 stats.definitions_checked++;
217 const size_t limit = opts.elimdefticks;
219 int status = cadical_kitten_solve (citten);
220 if (!exported)
221 goto ABORT;
222 if (status == 20) {
223 LOG ("sub-solver result UNSAT shows definition exists");
224 uint64_t learned;
225 unsigned reduced = cadical_kitten_compute_clausal_core (citten, &learned);
226 LOG ("1st sub-solver core of size %u original clauses out of %u",
227 reduced, exported);
228 for (int i = 2; i <= opts.elimdefcores; i++) {
232 int tmp = cadical_kitten_solve (citten);
233 CADICAL_assert (!tmp || tmp == 20);
234 if (!tmp) {
235 LOG ("aborting core extraction");
236 goto ABORT;
237 }
238#ifndef CADICAL_NDEBUG
239 unsigned previous = reduced;
240#endif
241 reduced = cadical_kitten_compute_clausal_core (citten, &learned);
242 LOG ("%d sub-solver core of size %u original clauses out of %u", i,
243 reduced, exported);
244 CADICAL_assert (reduced <= previous);
245#if not defined(LOGGING) && defined(CADICAL_NDEBUG)
246 (void) reduced;
247#endif
248 }
249 stats.definitions_extracted++;
250 eliminator.gatetype = DEF;
251 eliminator.definition_unit = 0;
252 cadical_kitten_traverse_core_ids (citten, &extractor, traverse_definition_core);
253 CADICAL_assert (eliminator.definition_unit);
254 int unit = 0;
255 if (eliminator.definition_unit == 2) {
256 unit = not_lit;
257 } else if (eliminator.definition_unit == 1)
258 unit = lit;
259
260 if (unit) {
261 stats.definition_units++;
262 VERBOSE (2, "one sided core "
263 "definition extraction yields "
264 "failed literal");
265 if (proof) {
266 if (lrat) {
267 extractor.unit = unit;
269 traverse_one_sided_core_lemma_with_lrat);
270 } else {
271 extractor.unit = unit;
273 traverse_one_sided_core_lemma);
274 }
275 } else
276 assign_unit (unit);
277 elim_propagate (eliminator, unit);
278 }
279 } else {
280 ABORT:
281 LOG ("sub-solver failed to show that definition exists");
282 }
283 stats.definition_ticks += cadical_kitten_current_ticks (citten);
284 return;
285}
286
287} // namespace CaDiCaL
288
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
Definition global.h:14
void cadical_kitten_shuffle_clauses(cadical_kitten *cadical_kitten)
unsigned cadical_kitten_compute_clausal_core(cadical_kitten *cadical_kitten, uint64_t *learned_ptr)
#define LOG(...)
uint64_t cadical_kitten_current_ticks(cadical_kitten *cadical_kitten)
void cadical_kitten_set_ticks_limit(cadical_kitten *cadical_kitten, uint64_t delta)
void cadical_kitten_traverse_core_clauses(cadical_kitten *cadical_kitten, void *state, void(*traverse)(void *, bool, size_t, const unsigned *))
int cadical_kitten_solve(cadical_kitten *cadical_kitten)
void cadical_kitten_trace_core(cadical_kitten *cadical_kitten, void *state, void(*trace)(void *, unsigned, unsigned, bool, size_t, const unsigned *, size_t, const unsigned *))
void citten_clause_with_id_and_exception(cadical_kitten *cadical_kitten, unsigned id, size_t size, const int *elits, unsigned except)
void cadical_kitten_shrink_to_clausal_core(cadical_kitten *cadical_kitten)
void cadical_kitten_traverse_core_ids(cadical_kitten *cadical_kitten, void *state, void(*traverse)(void *, unsigned))
Cube * p
Definition exorList.c:222
#define VERBOSE(...)
Definition message.hpp:58
int sign(int lit)
Definition util.hpp:22
@ DEF
Definition elim.hpp:31
unsigned long long size
Definition giaNewBdd.h:39
int lit
Definition satVec.h:130
unsigned definition_unit
Definition elim.hpp:49
vector< Clause * > gates
Definition elim.hpp:48
GateType gatetype
Definition elim.hpp:52
void citten_clear_track_log_terminate()
cadical_kitten * citten
Definition internal.hpp:277
signed char val(int lit) const
bool limit(const char *name, int)
unsigned lit2citten(int lit)
Definition internal.hpp:429
Occs & occs(int lit)
Definition internal.hpp:465
Internal * internal
Definition internal.hpp:311
void elim_propagate(Eliminator &, int unit)
void find_definition(Eliminator &, int)
vector< vector< int > > implicants
unsigned size
Definition vector.h:35
struct vector vector
Definition vector.h:24