ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
external.hpp
Go to the documentation of this file.
1#ifndef _external_hpp_INCLUDED
2#define _external_hpp_INCLUDED
3
4#include "global.h"
5
6/*------------------------------------------------------------------------*/
7
8#include "range.hpp"
9#include <unordered_map>
10#include <vector>
11
12/*------------------------------------------------------------------------*/
13
15
16namespace CaDiCaL {
17
18using namespace std;
19
20/*------------------------------------------------------------------------*/
21
22// The CaDiCaL code is split into three layers:
23//
24// Solver: facade object providing the actual API of the solver
25// External: communication layer between 'Solver' and 'Internal'
26// Internal: the actual solver code
27//
28// Note, that 'Solver' is defined in 'cadical.hpp' and 'solver.cpp', while
29// 'External' and 'Internal' in '{external,internal}.{hpp,cpp}'.
30//
31// Also note, that any user should access the library only through the
32// 'Solver' API. For the library internal 'Parser' code we make an
33// exception and allow access to both 'External' and 'Internal'. The former
34// to enforce the same external to internal mapping of variables and the
35// latter for profiling and messages. The same applies to 'App'.
36//
37// The 'External' class provided here stores the information needed to map
38// external variable indices to internal variables (actually literals).
39// This is helpful for shrinking the working size of the internal solver
40// after many variables become inactive. It will also help to provide
41// support for extended resolution in the future, since it allows to
42// introduce only internally visible variables (even though we do not know
43// how to support generating incremental proofs in this situation yet).
44//
45// External literals are usually called 'elit' and internal 'ilit'.
46
47/*------------------------------------------------------------------------*/
48
49struct Clause;
50struct Internal;
51struct CubesWithStatus;
52
53/*------------------------------------------------------------------------*/
54
55/*------------------------------------------------------------------------*/
56
57struct External {
58
59 /*==== start of state ==================================================*/
60
61 Internal *internal; // The actual internal solver.
62
63 int max_var; // External maximum variable index.
64 size_t vsize; // Allocated external size.
65
66 vector<bool> vals; // Current external (extended) assignment.
67 vector<int> e2i; // External 'idx' to internal 'lit'.
68
69 vector<int> assumptions; // External assumptions.
70 vector<int> constraint; // External constraint. Terminated by zero.
71
73 ext_units; // External units. Needed to compute LRAT for eclause
74 vector<bool> ext_flags; // to avoid duplicate units
75 vector<int> eclause; // External version of original input clause.
76 // The extension stack for reconstructing complete satisfying assignments
77 // (models) of the original external formula is kept in this external
78 // solver object. It keeps track of blocked clauses and clauses containing
79 // eliminated variable. These irredundant clauses are stored in terms of
80 // external literals on the 'extension' stack after mapping the
81 // internal literals given as arguments with 'externalize'.
82
83 bool extended; // Have been extended.
85 vector<int> extension; // Solution reconstruction extension stack.
86
87 vector<bool> witness; // Literal witness on extension stack.
88 vector<bool> tainted; // Literal tainted in adding literals.
89
90 vector<bool> ervars; // Variables added through Extended Resolution.
91
92 vector<unsigned> frozentab; // Reference counts for frozen variables.
93
94 // Regularly checked terminator if non-zero. The terminator is set from
95 // 'Solver::set (Terminator *)' and checked by 'Internal::terminating ()'.
96
98
99 // If there is a learner export learned clauses.
100
102
104 void export_learned_unit_clause (int ilit);
106
107 // If there is a listener for fixed assignments.
108
110
111 // If there is an external propagator.
112
114
115 vector<bool> is_observed; // Quick flag for each external variable
116
117 // Saved 'forgettable' original clauses coming from the external
118 // propagator. The value of the map starts with a Boolean flag indicating
119 // if the clause is still present or got already deleted, and then
120 // followed by the literals of the clause.
121 unordered_map<uint64_t, vector<int>> forgettable_original;
122
123 void add_observed_var (int elit);
124 void remove_observed_var (int elit);
125 void reset_observed_vars ();
126
127 bool observed (int elit);
128 bool is_witness (int elit);
129 bool is_decision (int elit);
130
131 void force_backtrack (size_t new_level);
132
133 //----------------------------------------------------------------------//
134
135 signed char *solution; // Given solution checking for debugging.
136 int solution_size; // Given solution checking for debugging.
137 vector<int> original; // Saved original formula for checking.
138
139 // If 'opts.checkfrozen' is set make sure that only literals are added
140 // which were never completely molten before. These molten literals are
141 // marked at the beginning of the 'solve' call. Note that variables
142 // larger than 'max_var' are not molten and can thus always be used in the
143 // future. Only needed to check and debug old style freeze semantics.
144 //
146
147 //----------------------------------------------------------------------//
148
149 const Range vars; // Provides safe variable iterations.
150
151 /*==== end of state ====================================================*/
152
153 // These two just factor out common sanity (CADICAL_assertion) checking code.
154
155 inline int vidx (int elit) const {
156 CADICAL_assert (elit);
157 CADICAL_assert (elit != INT_MIN);
158 int res = abs (elit);
159 CADICAL_assert (res <= max_var);
160 return res;
161 }
162
163 inline int vlit (int elit) const {
164 CADICAL_assert (elit);
165 CADICAL_assert (elit != INT_MIN);
166 CADICAL_assert (abs (elit) <= max_var);
167 return elit;
168 }
169
170 inline bool is_valid_input (int elit) {
171 CADICAL_assert (elit);
172 CADICAL_assert (elit != INT_MIN);
173 int eidx = abs (elit);
174 return eidx > max_var || !ervars[eidx];
175 }
176
177 /*----------------------------------------------------------------------*/
178
179 // The following five functions push individual literals or clauses on the
180 // extension stack. They all take internal literals as argument, and map
181 // them back to external literals first, before pushing them on the stack.
182
184
185 // Our general version of extension stacks always pushes a set of witness
186 // literals (for variable elimination the literal of the eliminated
187 // literal and for blocked clauses the blocking literal) followed by all
188 // the clause literals starting with and separated by zero.
189 //
192
196 int other);
197
198 // The main 'extend' function which extends an internal assignment to an
199 // external assignment using the extension stack (and sets 'extended').
200 //
201 void extend ();
202 void conclude_sat ();
203
204 /*----------------------------------------------------------------------*/
205
206 // Marking external literals.
207
208 unsigned elit2ulit (int elit) const {
209 CADICAL_assert (elit);
210 CADICAL_assert (elit != INT_MIN);
211 const int idx = abs (elit) - 1;
212 CADICAL_assert (idx <= max_var);
213 return 2u * idx + (elit < 0);
214 }
215
216 bool marked (const vector<bool> &map, int elit) const {
217 const unsigned ulit = elit2ulit (elit);
218 return ulit < map.size () ? map[ulit] : false;
219 }
220
221 void mark (vector<bool> &map, int elit) {
222 const unsigned ulit = elit2ulit (elit);
223 if (ulit >= map.size ())
224 map.resize (ulit + 1, false);
225 map[ulit] = true;
226 }
227
228 void unmark (vector<bool> &map, int elit) {
229 const unsigned ulit = elit2ulit (elit);
230 if (ulit < map.size ())
231 map[ulit] = false;
232 }
233
234 /*----------------------------------------------------------------------*/
235
237 const vector<int> &clause, const vector<int> &witness, int64_t id);
238
239 void push_id_on_extension_stack (int64_t id);
240
241 // Restore a clause, which was pushed on the extension stack.
244 const int64_t id);
245
246 void restore_clauses ();
247
248 /*----------------------------------------------------------------------*/
249
250 // Explicitly freeze and melt literals (instead of just freezing
251 // internally and implicitly assumed literals). Passes on freezing and
252 // melting to the internal solver, which has separate frozen counters.
253
254 void freeze (int elit);
255 void melt (int elit);
256
257 bool frozen (int elit) {
258 CADICAL_assert (elit);
259 CADICAL_assert (elit != INT_MIN);
260 int eidx = abs (elit);
261 if (eidx > max_var)
262 return false;
263 if (eidx >= (int) frozentab.size ())
264 return false;
265 return frozentab[eidx] > 0;
266 }
267
268 /*----------------------------------------------------------------------*/
269
270 External (Internal *);
271 ~External ();
272
273 void enlarge (int new_max_var); // Enlarge allocated 'vsize'.
274 void init (int new_max_var,
275 bool extension = false); // Initialize up-to 'new_max_var'.
276
277 int internalize (
278 int,
279 bool extension = false); // Translate external to internal literal.
280
281 /*----------------------------------------------------------------------*/
282
283 // According to the CaDiCaL API contract (as well as IPASIR) we have to
284 // forget about the previous assumptions after a 'solve' call. This
285 // should however be delayed until we transition out of an 'UNSATISFIED'
286 // state, i.e., after no more 'failed' calls are expected. Note that
287 // 'failed' requires to know the failing assumptions, and the 'failed'
288 // status of those should cleared before at start of the next 'solve'.
289 // As a consequence 'reset_assumptions' is only called from
290 // 'transition_to_unknown_state' in API calls in 'solver.cpp'.
291
292 void reset_assumptions ();
293
294 // Similarly to 'failed', 'conclude' needs to know about failing
295 // assumptions and therefore needs to be reset when leaving the
296 // 'UNSATISFIED' state.
297 //
298 void reset_concluded ();
299
300 // Similarly a valid external assignment obtained through 'extend' has to
301 // be reset at each point it risks to become invalid. This is done
302 // in the external layer in 'external.cpp' functions..
303
304 void reset_extended ();
305
306 // Finally, the semantics of incremental solving also require that limits
307 // are only valid for the next 'solve' call. Since the limits can not
308 // really be queried, handling them is less complex and they are just
309 // reset immediately at the end of 'External::solve'.
310
311 void reset_limits ();
312
313 /*----------------------------------------------------------------------*/
314
315 // Proxies to IPASIR functions.
316
317 void add (int elit);
318 void assume (int elit);
319 int solve (bool preprocess_only);
320
321 // We call it 'ival' as abbreviation for 'val' with 'int' return type to
322 // avoid bugs due to using 'signed char tmp = val (lit)', which might turn
323 // a negative value into a positive one (happened in 'extend').
324 //
325 inline int ival (int elit) const {
326 CADICAL_assert (elit != INT_MIN);
327 int eidx = abs (elit);
328 bool val = false;
329 if (eidx <= max_var && (size_t) eidx < vals.size ())
330 val = vals[eidx];
331 if (elit < 0)
332 val = !val;
333 return val ? elit : -elit;
334 }
335
336 bool flip (int elit);
337 bool flippable (int elit);
338
339 bool failed (int elit);
340
341 void terminate ();
342
343 // Other important non IPASIR functions.
344
345 /*----------------------------------------------------------------------*/
346
347 // Add literal to external constraint.
348 //
349 void constrain (int elit);
350
351 // Returns true if 'solve' returned 20 because of the constraint.
352 //
353 bool failed_constraint ();
354
355 // Deletes the current constraint clause. Called on
356 // 'transition_to_unknown_state' and if a new constraint is added. Can be
357 // called directly using the API.
358 //
359 void reset_constraint ();
360
361 /*----------------------------------------------------------------------*/
362
364 void implied (std::vector<int> &entrailed);
365 void conclude_unknown ();
366
367 /*----------------------------------------------------------------------*/
368 int lookahead ();
370
371 int fixed (int elit) const; // Implemented in 'internal.hpp'.
372
373 /*----------------------------------------------------------------------*/
374
375 void phase (int elit);
376 void unphase (int elit);
377
378 /*----------------------------------------------------------------------*/
379
380 // Traversal functions for the witness stack and units. The explanation
381 // in 'external.cpp' for why we have to distinguish these cases.
382
387
388 /*----------------------------------------------------------------------*/
389
390 // Copy flags for determining preprocessing state.
391
392 void copy_flags (External &other) const;
393
394 /*----------------------------------------------------------------------*/
395
396 // Check solver behaves as expected during testing and debugging.
397
400 void check_failing ();
401
406
411
416
421
426
427 void check_assignment (int (External::*assignment) (int) const);
428
429 void check_satisfiable ();
430 void check_unsatisfiable ();
431
432 void check_solve_result (int res);
433
435
436 /*----------------------------------------------------------------------*/
437
438 // For debugging and testing only. See 'solution.hpp' for more details.
439 // TODO: if elit > solution_size, elit is an extension variable. For now
440 // the clause will count as satisfied regardless. For the future one
441 // should check that actually there is one consistent extension for the
442 // solution that satisfies the clauses with this extension variable (by
443 // setting it to a value once a clause is learned which is not satisfied
444 // already).
445 //
446 inline int sol (int elit) const {
448 CADICAL_assert (elit != INT_MIN);
449 int eidx = abs (elit);
450 if (eidx > max_var)
451 return 0;
452 else if (eidx > solution_size)
453 return elit;
454 signed char value = solution[eidx];
455 if (!value)
456 return 0;
457 if (elit < 0)
458 value = -value;
459 return value > 0 ? elit : -elit;
460 }
461};
462
463} // namespace CaDiCaL
464
466
467#endif
#define ABC_NAMESPACE_CXX_HEADER_START
#define ABC_NAMESPACE_CXX_HEADER_END
#define CADICAL_assert(ignore)
Definition global.h:14
ABC_NAMESPACE_IMPL_START typedef signed char value
void map()
void check_shrunken_clause(Clause *c)
Definition external.hpp:422
bool traverse_all_non_frozen_units_as_witnesses(WitnessIterator &)
void constrain(int elit)
vector< bool > ext_flags
Definition external.hpp:74
void enlarge(int new_max_var)
bool is_witness(int elit)
CaDiCaL::CubesWithStatus generate_cubes(int, int)
const Range vars
Definition external.hpp:149
void check_learned_unit_clause(int unit)
Definition external.hpp:412
void check_solution_on_learned_unit_clause(int unit)
bool traverse_witnesses_backward(WitnessIterator &)
bool is_valid_input(int elit)
Definition external.hpp:170
vector< bool > tainted
Definition external.hpp:88
vector< bool > is_observed
Definition external.hpp:115
void push_witness_literal_on_extension_stack(int ilit)
bool traverse_witnesses_forward(WitnessIterator &)
bool marked(const vector< bool > &map, int elit) const
Definition external.hpp:216
void check_learned_empty_clause()
Definition external.hpp:407
bool is_decision(int elit)
signed char * solution
Definition external.hpp:135
int ival(int elit) const
Definition external.hpp:325
void export_learned_unit_clause(int ilit)
bool frozen(int elit)
Definition external.hpp:257
void check_no_solution_after_learning_empty_clause()
vector< bool > moltentab
Definition external.hpp:145
vector< bool > witness
Definition external.hpp:87
void check_solution_on_shrunken_clause(Clause *)
Terminator * terminator
Definition external.hpp:97
void restore_clause(const vector< int >::const_iterator &begin, const vector< int >::const_iterator &end, const int64_t id)
void push_id_on_extension_stack(int64_t id)
void push_external_clause_and_witness_on_extension_stack(const vector< int > &clause, const vector< int > &witness, int64_t id)
void implied(std::vector< int > &entrailed)
unsigned elit2ulit(int elit) const
Definition external.hpp:208
vector< int64_t > ext_units
Definition external.hpp:73
void check_assignment(int(External::*assignment)(int) const)
vector< int > extension
Definition external.hpp:85
Learner * learner
Definition external.hpp:101
vector< int > original
Definition external.hpp:137
int vlit(int elit) const
Definition external.hpp:163
unordered_map< uint64_t, vector< int > > forgettable_original
Definition external.hpp:121
void push_zero_on_extension_stack()
vector< int > constraint
Definition external.hpp:70
bool flippable(int elit)
void remove_observed_var(int elit)
void add_observed_var(int elit)
void copy_flags(External &other) const
bool traverse_all_frozen_units_as_clauses(ClauseIterator &)
vector< bool > vals
Definition external.hpp:66
vector< unsigned > frozentab
Definition external.hpp:92
void push_clause_literal_on_extension_stack(int ilit)
void check_learned_clause()
Definition external.hpp:417
Internal * internal
Definition external.hpp:61
vector< int > eclause
Definition external.hpp:75
void mark(vector< bool > &map, int elit)
Definition external.hpp:221
bool observed(int elit)
int solve(bool preprocess_only)
vector< int > e2i
Definition external.hpp:67
void check_solution_on_learned_clause()
FixedAssignmentListener * fixed_listener
Definition external.hpp:109
void export_learned_large_clause(const vector< int > &)
void push_binary_clause_on_extension_stack(int64_t id, int witness, int other)
int sol(int elit) const
Definition external.hpp:446
void force_backtrack(size_t new_level)
void init(int new_max_var, bool extension=false)
void push_clause_on_extension_stack(Clause *)
int vidx(int elit) const
Definition external.hpp:155
vector< bool > ervars
Definition external.hpp:90
ExternalPropagator * propagator
Definition external.hpp:113
int fixed(int elit) const
void unmark(vector< bool > &map, int elit)
Definition external.hpp:228
void check_solve_result(int res)
vector< int > assumptions
Definition external.hpp:69
int internalize(int, bool extension=false)