ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
cadical.hpp
Go to the documentation of this file.
1#ifndef _cadical_hpp_INCLUDED
2#define _cadical_hpp_INCLUDED
3
4#include "global.h"
5
6#include <cstdint>
7#include <cstdio>
8#include <vector>
9
11
12namespace CaDiCaL {
13
14/*========================================================================*/
15
16// This provides the actual API of the CaDiCaL solver, which is implemented
17// in the class 'Solver' below. Beside its constructor and destructor most
18// important is the IPASIR part which you can find between 'BEGIN IPASIR'
19// and 'END IPASIR' comments below. The following '[Example]' below might
20// also be a good starting point to understand the API.
21
22/*========================================================================*/
23
24// The SAT competition standardized the exit code of SAT solvers to the
25// following which then is also used return code for 'solve' functions.
26// In the following example we use those constants for brevity though.
27
28enum Status {
32};
33
34/*========================================================================*/
35
36// [Example]
37//
38// The internal solver state follows the IPASIR API model used in the
39// incremental track of the SAT competition. State transitions are
40// triggered by member function calls, declared and described below.
41//
42// Consider the following code (from 'test/api/example.cpp') of API usage:
43//
44// CaDiCaL::Solver * solver = new CaDiCaL::Solver;
45//
46// // ------------------------------------------------------------------
47// // Encode Problem and check without assumptions.
48//
49// enum { TIE = 1, SHIRT = 2 };
50//
51// solver->add (-TIE), solver->add (SHIRT), solver->add (0);
52// solver->add (TIE), solver->add (SHIRT), solver->add (0);
53// solver->add (-TIE), solver->add (-SHIRT), solver->add (0);
54//
55// int res = solver->solve (); // Solve instance.
56// CADICAL_assert (res == 10); // Check it is 'SATISFIABLE'.
57//
58// res = solver->val (TIE); // Obtain assignment of 'TIE'.
59// CADICAL_assert (res < 0); // Check 'TIE' assigned to 'false'.
60//
61// res = solver->val (SHIRT); // Obtain assignment of 'SHIRT'.
62// CADICAL_assert (res > 0); // Check 'SHIRT' assigned to 'true'.
63//
64// // ------------------------------------------------------------------
65// // Incrementally solve again under one assumption.
66//
67// solver->assume (TIE); // Now force 'TIE' to true.
68//
69// res = solver->solve (); // Solve again incrementally.
70// CADICAL_assert (res == 20); // Check it is 'UNSATISFIABLE'.
71//
72// res = solver->failed (TIE); // Check 'TIE' responsible.
73// CADICAL_assert (res); // Yes, 'TIE' in core.
74//
75// res = solver->failed (SHIRT); // Check 'SHIRT' responsible.
76// CADICAL_assert (!res); // No, 'SHIRT' not in core.
77//
78// // ------------------------------------------------------------------
79// // Incrementally solve once more under another assumption.
80//
81// solver->assume (-SHIRT); // Now force 'SHIRT' to false.
82//
83// res = solver->solve (); // Solve again incrementally.
84// CADICAL_assert (res == 20); // Check it is 'UNSATISFIABLE'.
85//
86// res = solver->failed (TIE); // Check 'TIE' responsible.
87// CADICAL_assert (!res); // No, 'TIE' not in core.
88//
89// res = solver->failed (-SHIRT); // Check '!SHIRT' responsible.
90// CADICAL_assert (res); // Yes, '!SHIRT' in core.
91//
92// // ------------------------------------------------------------------
93//
94// delete solver;
95
96/*========================================================================*/
97
98// [States and Transitions]
99//
100// Compared to IPASIR we also use an 'ADDING' state in which the solver
101// stays while adding non-zero literals until the clause is completed
102// through adding a zero literal. The additional 'INITIALIZING',
103// 'CONFIGURING' and 'DELETING' states are also not part of IPASIR but also
104// useful for testing and debugging.
105//
106// We have the following transitions which are all synchronous except for
107// the reentrant 'terminate' call:
108//
109// new
110// INITIALIZING --------------------------> CONFIGURING
111//
112// set / trace
113// CONFIGURING --------------------------> CONFIGURING
114//
115// add (non zero literal)
116// VALID --------------------------> ADDING
117//
118// add (zero literal)
119// VALID --------------------------> STEADY
120//
121// assume (non zero literal)
122// READY --------------------------> STEADY
123//
124// solve
125// READY --------------------------> SOLVING
126//
127// (internal)
128// SOLVING --------------------------> SOLVED
129//
130// val (non zero literal)
131// SATISFIED --------------------------> SATISFIED
132//
133// failed (non zero literal)
134// UNSATISFIED --------------------------> UNSATISFIED
135//
136// implied (non zero literal)
137// INCONCLUSIVE --------------------------> INCONCLUSIVE
138//
139// delete
140// VALID --------------------------> DELETING
141//
142// where
143//
144// SOLVED = SATISFIED | UNSATISFIED | INCONCLUSIVE
145// READY = CONFIGURING | STEADY | SOLVED
146// VALID = READY | ADDING
147// INVALID = INITIALIZING | DELETING
148//
149// The 'SOLVING' state is only visible in different contexts, i.e., from
150// another thread or from a signal handler. It is used to implement
151// 'terminate'. Here is the only asynchronous transition:
152//
153// terminate (asynchronously)
154// SOLVING -------------------------> STEADY
155//
156// The important behaviour to remember is that adding, assuming or
157// constraining a literal (immediately) destroys the satisfying assignment
158// in the 'SATISFIED' state and vice versa resets all assumptions in the
159// 'UNSATISFIED' state. This is exactly the behaviour required by the IPASIR
160// interface.
161//
162// Furthermore, the model can only be queried through 'val' in the
163// 'SATISFIED' state, while extracting failed assumptions with 'failed' only
164// in the 'UNSATISFIED' state. Solving can only be started in the 'STEADY '
165// or 'CONFIGURING' state or after the previous call to 'solve' yielded an
166// 'INCONCLUSIVE , 'SATISFIED' or 'UNSATISFIED' state.
167//
168// All literals have to be valid literals too, i.e., 32-bit integers
169// different from 'INT_MIN'. If any of these requirements is violated the
170// solver aborts with an 'API contract violation' message.
171//
172// HINT: If you do not understand why a contract is violated you can run
173// 'mobical' on the failing API call trace. Point the environment variable
174// 'CADICAL_API_TRACE' to the file where you want to save the trace during
175// execution of your program linking against the library. You probably need
176// for 'mobical' to use the option '--do-not-enforce-contracts' though to
177// force running into the same contract violation.
178//
179// Additional API calls (like 'freeze' and 'melt') do not change the state
180// of the solver and are all described below.
181
182/*========================================================================*/
183
184// States are represented by a bit-set in order to combine them.
185
186enum State {
187 INITIALIZING = 1, // during initialization (invalid)
188 CONFIGURING = 2, // configure options (with 'set')
189 STEADY = 4, // ready to call 'solve'
190 ADDING = 8, // adding clause literals (zero missing)
191 SOLVING = 16, // while solving (within 'solve')
192 SATISFIED = 32, // satisfiable allows 'val'
193 UNSATISFIED = 64, // unsatisfiable allows 'failed'
194 DELETING = 128, // during and after deletion (invalid)
195 INCONCLUSIVE = 256, // unknown allows 'implied'
196
197 // These combined states are used to check contracts.
198
202};
203
204/*------------------------------------------------------------------------*/
205
206// Opaque classes needed in the API and declared in the same namespace.
207
208class File;
209class Testing;
210struct Internal;
211struct External;
212
213/*------------------------------------------------------------------------*/
214
215// Forward declaration of call-back classes. See bottom of this file.
216
217class Learner;
218class FixedAssignmentListener;
219class Terminator;
220class ClauseIterator;
221class WitnessIterator;
222class ExternalPropagator;
223class Tracer;
224struct InternalTracer;
225class FileTracer;
226class StatTracer;
227
228/*------------------------------------------------------------------------*/
229
230class Solver {
231
232public:
233 // ====== BEGIN IPASIR ===================================================
234
235 // This section implements the corresponding IPASIR functionality.
236
237 Solver ();
238 ~Solver ();
239
240 static const char *signature (); // name of this library
241
242 // Core functionality as in the IPASIR incremental SAT solver interface.
243 // (recall 'READY = CONFIGURING | STEADY | SATISFIED | UNSATISFIED').
244 // Further note that 'lit' is required to be different from 'INT_MIN' and
245 // different from '0' except for 'add'.
246
247 // Add valid literal to clause or zero to terminate clause.
248 //
249 // require (VALID) // recall 'VALID = READY | ADDING'
250 // if (lit) ensure (ADDING) // and thus VALID but not READY
251 // if (!lit) ensure (STEADY ) // and thus READY
252 //
253 void add (int lit);
254
255 // Here are functions simplifying clause addition. The given literals
256 // should all be valid (different from 'INT_MIN' and different from '0').
257 //
258 // require (VALID)
259 // ensure (STEADY )
260 //
261 void clause (int); // Add unit clause.
262 void clause (int, int); // Add binary clause.
263 void clause (int, int, int); // Add ternary clause.
264 void clause (int, int, int, int); // Add quaternary clause.
265 void clause (int, int, int, int, int); // Add quinternary clause.
266 void clause (const std::vector<int> &); // Add literal vector as clause.
267 void clause (const int *, size_t); // Add literal array as clause.
268
269 // This function can be used to check if the formula is already
270 // inconsistent (contains the empty clause or was proven to be
271 // root-level unsatisfiable).
272
273 bool inconsistent ();
274
275 // Assume valid non zero literal for next call to 'solve'. These
276 // assumptions are reset after the call to 'solve' as well as after
277 // returning from 'simplify' and 'lookahead.
278 //
279 // require (READY)
280 // ensure (STEADY )
281 //
282 void assume (int lit);
283
284 // Try to solve the current formula. Returns
285 //
286 // 0 = UNKNOWN (limit reached or interrupted through 'terminate')
287 // 10 = SATISFIABLE
288 // 20 = UNSATISFIABLE
289 //
290 // require (READY)
291 // ensure (INCONCLUSIVE | SATISFIED | UNSATISFIED)
292 //
293 // Note, that while in this call the solver actually transitions to state
294 // 'SOLVING', which however is only visible from a different context,
295 // i.e., from a different thread or from a signal handler. Only right
296 // before returning from this call it goes into a 'READY' state.
297 //
298 int solve ();
299
300 // Get value (-lit=false, lit=true) of valid non-zero literal.
301 //
302 // require (SATISFIED)
303 // ensure (SATISFIED)
304 //
305 int val (int lit);
306
307 // Try to flip the value of the given literal without falsifying the
308 // formula. Returns 'true' if this was successful. Otherwise the model is
309 // not changed and 'false' is returned. If a literal was eliminated or
310 // substituted flipping will fail on that literal and in particular the
311 // solver will not taint it nor restore any clauses.
312 //
313 // The 'flip' function can only flip the value of a variables not acting
314 // as witness on the reconstruction stack.
315 //
316 // As a side effect of calling this function first all assigned variables
317 // are propagated again without using blocking literal. Thus the first
318 // call to this function after obtaining a model adds a substantial
319 // overhead. Subsequent calls will not need to properly propagate again.
320 //
321 // Furthermore if the reconstruction stack is non-empty and has been
322 // traversed to reconstruct a full extended model for eliminated
323 // variables (and to satisfy removed blocked clauses), the values of these
324 // witness variables obtained via 'val' before become invalid. The user
325 // thus will need to call 'val' again after calling 'flip' which will
326 // trigger then a traversal of the reconstruction stack.
327 //
328 // So try to avoid mixing 'flip' and 'val' (for efficiency only).
329 // Further, this functionality is currently not supported in the presence
330 // of an external propagator.
331 //
332 // require (SATISFIED)
333 // ensure (SATISFIED)
334 //
335 bool flip (int lit);
336
337 // Same as 'flip' without actually flipping it. This functionality is
338 // currently not supported in the presence of an external propagator.
339 //
340 // require (SATISFIED)
341 // ensure (SATISFIED)
342 //
343 bool flippable (int lit);
344
345 // Determine whether the valid non-zero literal is in the core.
346 // Returns 'true' if the literal is in the core and 'false' otherwise.
347 // Note that the core does not have to be minimal.
348 //
349 // require (UNSATISFIED)
350 // ensure (UNSATISFIED)
351 //
352 bool failed (int lit);
353
354 // Add call-back which is checked regularly for termination. There can
355 // only be one terminator connected. If a second (non-zero) one is added
356 // the first one is implicitly disconnected.
357 //
358 // require (VALID)
359 // ensure (VALID)
360 //
361 void connect_terminator (Terminator *terminator);
362 void disconnect_terminator ();
363
364 // Add call-back which allows to export learned clauses.
365 //
366 // require (VALID)
367 // ensure (VALID)
368 //
369 void connect_learner (Learner *learner);
370 void disconnect_learner ();
371
372 // ====== END IPASIR =====================================================
373
374 // Add call-back which allows to observe when a variable is fixed.
375 //
376 // require (VALID)
377 // ensure (VALID)
378 //
379 void connect_fixed_listener (FixedAssignmentListener *fixed_listener);
381
382 // ====== BEGIN IPASIR-UP ================================================
383
384 // Add call-back which allows to learn, propagate and backtrack based on
385 // external constraints. Only one external propagator can be connected
386 // and after connection every related variables must be 'observed' (use
387 // 'add_observed_var' function).
388 // Disconnection of the external propagator resets all the observed
389 // variables.
390 //
391 // require (VALID)
392 // ensure (VALID)
393 //
396
397 // Mark as 'observed' those variables that are relevant to the external
398 // propagator. External propagation, clause addition during search and
399 // notifications are all over these observed variables.
400 // A variable can not be observed without having an external propagator
401 // connected. Observed variables are "frozen" internally, and so
402 // inprocessing will not consider them as candidates for elimination.
403 // An observed variable is allowed to be a fresh variable and it can be
404 // added also during solving.
405 //
406 // require (VALID_OR_SOLVING)
407 // ensure (VALID_OR_SOLVING)
408 //
409 void add_observed_var (int var);
410
411 // Removes the 'observed' flag from the given variable. A variable can be
412 // set unobserved only between solve calls, not during it (to guarantee
413 // that no yet unexplained external propagation involves it).
414 //
415 // require (VALID)
416 // ensure (VALID)
417 //
418 void remove_observed_var (int var);
419
420 // Removes all the 'observed' flags from the variables. Disconnecting the
421 // propagator invokes this step as well.
422 //
423 // require (VALID)
424 // ensure (VALID)
425 //
426 void reset_observed_vars ();
427
428 // Get reason of valid observed literal (true = it is an observed variable
429 // and it got assigned by a decision during the CDCL loop. Otherwise:
430 // false.
431 //
432 // require (VALID_OR_SOLVING)
433 // ensure (VALID_OR_SOLVING)
434 //
435 bool is_decision (int lit);
436
437 // Force solve to backtrack to certain decision level. Can be called only
438 // during 'cb_decide' of a connected External Propagator.
439 // Invoking in any other time will not have an effect.
440 // If the call had an effect, the External Propagator will be notified
441 // about the backtrack via 'notify_backtrack'.
442 //
443 // require (SOLVING)
444 // ensure (SOLVING)
445 //
446 void force_backtrack (size_t new_level);
447
448 // ====== END IPASIR-UP ==================================================
449
450 //------------------------------------------------------------------------
451 // Adds a literal to the constraint clause. Same functionality as 'add'
452 // but the clause only exists for the next call to solve (same lifetime as
453 // assumptions). Only one constraint may exists at a time. A new
454 // constraint replaces the old. The main application of this functionality
455 // is the model checking algorithm IC3. See our FMCAD'21 paper
456 // [FroleyksBiere-FMCAD'19] for more details.
457 //
458 // Add valid literal to the constraint clause or zero to terminate it.
459 //
460 // require (VALID) // recall 'VALID = READY |
461 // ADDING' if (lit) ensure (ADDING) // and thus VALID but not
462 // READY if (!lit) && !adding_clause ensure (STEADY ) // and thus READY
463 //
464 void constrain (int lit);
465
466 // Determine whether the constraint was used to proof the
467 // unsatisfiability. Note that the formula might still be unsatisfiable
468 // without the constraint.
469 //
470 // require (UNSATISFIED)
471 // ensure (UNSATISFIED)
472 //
473 bool constraint_failed ();
474
475 // Collects a subset of those literals that are implied by unit
476 // propagation by assuming the currently defined (potentially empty) set
477 // of assumptions (see IPASIR assume(lit)) function. In case unit
478 // propgation over the defined set of assumptions (or over the clause
479 // database on its own) leads to conflict, the function returns 20 and the
480 // content of 'implicants' is undefined. In case unit propagation happens
481 // to satisfy all the clauses (not probable, but not impossible), the
482 // function returns 10 and 'implicants' is a solution of the current
483 // formula under the current assumptions (after solution reconstruction).
484 // In any other case, the function returns 0 (indicating 'UNKNOWN') and
485 // 'implicants' lists the non-conflicting current value of the trail.
486
487 // Returns
488 //
489 // 0 = UNKNOWN (unit propagation did not lead to a conflict nor to a
490 // complete assignment, or limit reached or interrupted
491 // through 'terminate')
492 // 10 = SATISFIABLE
493 // 20 = UNSATISFIABLE
494
495 // require (READY)
496 // ensure (INCONCLUSIVE | SATISFIED | UNSATISFIED)
497 int propagate ();
498
499 //
500 // require (INCONCLUSIVE)
501 // ensure (INCONCLUSIVE)
502 //
503 void implied (std::vector<int> &implicants);
504
505 //------------------------------------------------------------------------
506 // This function determines a good splitting literal. The result can be
507 // zero if the formula is proven to be satisfiable or unsatisfiable. This
508 // can then be checked by 'state ()'. If the formula is empty and
509 // the function is not able to determine satisfiability also zero is
510 // returned but the state remains steady.
511 //
512 // require (READY)
513 // ensure (INCONCLUSIVE |SATISFIED|UNSATISFIED)
514 //
515 int lookahead (void);
516
519 std::vector<std::vector<int>> cubes;
520 };
521
522 CubesWithStatus generate_cubes (int, int min_depth = 0);
523
524 void reset_assumptions ();
525 void reset_constraint ();
526
527 // Return the current state of the solver as defined above.
528 //
529 const State &state () const { return _state; }
530
531 // Similar to 'state ()' but using the standard competition exit codes of
532 // '10' for 'SATISFIABLE', '20' for 'UNSATISFIABLE' and '0' otherwise.
533 //
534 int status () const {
535 if (_state == SATISFIED)
536 return 10;
537 else if (_state == UNSATISFIED)
538 return 20;
539 else
540 return 0;
541 }
542
543 /*----------------------------------------------------------------------*/
544
545 static const char *version (); // return version string
546
547 /*----------------------------------------------------------------------*/
548 // Copy 'this' into a fresh 'other'. The copy procedure is not a deep
549 // clone, but only copies irredundant clauses and units. It also makes
550 // sure that witness reconstruction works with the copy as with the
551 // original formula such that both solvers have the same models.
552 // Assumptions are not copied. Options however are copied as well as
553 // flags which remember the current state of variables in preprocessing.
554 //
555 // require (READY) // for 'this'
556 // ensure (READY) // for 'this'
557 //
558 // other.require (CONFIGURING)
559 // other.ensure (CONFIGURING | STEADY )
560 //
561 void copy (Solver &other) const;
562
563 /*----------------------------------------------------------------------*/
564 // Variables are usually added and initialized implicitly whenever a
565 // literal is used as an argument except for the functions 'val', 'fixed',
566 // 'failed' and 'frozen'. However, the library internally keeps a maximum
567 // variable index, which can be queried.
568 // With factor (BVA) the solver might also add new variables. In that case
569 // the user is required to use this to check which variables are currently
570 // free before adding new variables of their own.
571 // The alternative is to reserve variables in batches with
572 // 'reserve_difference'. Using 'reserve' in combination with any technique
573 // that could add variables (currently only factor) is not advised.
574 //
575 // require (VALID | SOLVING)
576 // ensure (VALID | SOLVING)
577 //
578 int vars ();
579
580 // Increase the maximum variable index explicitly. This function makes
581 // sure that at least 'min_max_var' variables are initialized. Since it
582 // might need to reallocate tables, it destroys a satisfying assignment
583 // and has the same state transition and conditions as 'assume' etc.
584 //
585 // require (READY)
586 // ensure (STEADY )
587 //
588 void reserve (int min_max_var);
589
590 // Increase the maximum variable index by a number of new variables.
591 // initializes 'number_of_vars' new variables and protects them from
592 // being used by the solver as extension variables (BVA).
593 // It returns the new maximum variable index which is the highest
594 // variable name of the consecutive range of newly reserved variables.
595 // It has the same state transition and conditions as 'reserve' above.
596 //
597 // require (READY)
598 // ensure (STEADY )
599 //
600 int reserve_difference (int number_of_vars);
601
602#ifndef CADICAL_NTRACING
603 //------------------------------------------------------------------------
604 // This function can be used to write API calls to a file. The same
605 // format is used which 'mobical' can read, execute and also shrink
606 // through delta debugging.
607 //
608 // Tracing API calls can also be achieved by using the environment
609 // variable 'CADICAL_API_TRACE'. That alternative is useful if you do not
610 // want to change the source code using the solver, e.g., if you only have
611 // a binary with the solver linked in. However, that method only allows
612 // to trace one solver instance, while with the following function API
613 // tracing can be enabled for different solver instances individually.
614 //
615 // The solver will flush the file after every trace API call but does not
616 // close it during deletion. It remains owned by the user of the library.
617 //
618 // require (VALID)
619 // ensure (VALID)
620 //
621 void trace_api_calls (FILE *file);
622#endif
623
624 //------------------------------------------------------------------------
625 // Option handling.
626
627 // Determine whether 'name' is a valid option name.
628 //
629 static bool is_valid_option (const char *name);
630
631 // Determine whether 'name' enables a specific preprocessing technique.
632 //
633 static bool is_preprocessing_option (const char *name);
634
635 // Determine whether 'arg' is a valid long option of the form '--<name>',
636 // '--<name>=<val>' or '--no-<name>' similar to 'set_long_option' below.
637 // Legal values are 'true', 'false', or '[-]<mantissa>[e<exponent>]'.
638
639 static bool is_valid_long_option (const char *arg);
640
641 // Get the current value of the option 'name'. If 'name' is invalid then
642 // zero is returned. Here '--...' arguments as invalid options.
643 //
644 int get (const char *name);
645
646 // Set the default verbose message prefix (default "c ").
647 //
648 void prefix (const char *verbose_message_prefix);
649
650 // Explicit version of setting an option. If the option '<name>' exists
651 // and '<val>' can be parsed then 'true' is returned. If the option value
652 // is out of range the actual value is computed as the closest (minimum or
653 // maximum) value possible, but still 'true' is returned.
654 //
655 // require (CONFIGURING)
656 // ensure (CONFIGURING)
657 //
658 // Thus options can only bet set right after initialization.
659 //
660 bool set (const char *name, int val);
661
662 // This function accepts options in command line syntax:
663 //
664 // '--<name>=<val>', '--<name>', or '--no-<name>'
665 //
666 // It actually calls the previous 'set' function after parsing 'arg'. The
667 // same values are expected as for 'is_valid_long_option' above and as
668 // with 'set' any value outside of the range of legal values for a
669 // particular option are set to either the minimum or maximum depending on
670 // which side of the valid interval they lie.
671 //
672 // require (CONFIGURING)
673 // ensure (CONFIGURING)
674 //
675 bool set_long_option (const char *arg);
676
677 // Determine whether 'name' is a valid configuration.
678 //
679 static bool is_valid_configuration (const char *);
680
681 // Overwrite (some) options with the forced values of the configuration.
682 // The result is 'true' iff the 'name' is a valid configuration.
683 //
684 // require (CONFIGURING)
685 // ensure (CONFIGURING)
686 //
687 bool configure (const char *);
688
689 // Increase preprocessing and inprocessing limits by '10^<val>'. Values
690 // below '0' are ignored and values above '9' are reduced to '9'.
691 //
692 // require (READY)
693 // ensure (READY)
694 //
695 void optimize (int val);
696
697 // Specify search limits, where currently 'name' can be "conflicts",
698 // "decisions", "preprocessing", or "localsearch". The first two limits
699 // are unbounded by default. Thus using a negative limit for conflicts or
700 // decisions switches back to the default of unlimited search (for that
701 // particular limit). The preprocessing limit determines the number of
702 // preprocessing rounds, which is zero by default. Similarly, the local
703 // search limit determines the number of local search rounds (also zero by
704 // default). As with 'set', the return value denotes whether the limit
705 // 'name' is valid. These limits are only valid for the next 'solve' or
706 // 'simplify' call and reset to their default after 'solve' returns (as
707 // well as overwritten and reset during calls to 'simplify' and
708 // 'lookahead'). We actually also have an internal "terminate" limit
709 // which however should only be used for testing and debugging.
710 //
711 // require (READY)
712 // ensure (READY)
713 //
714 bool limit (const char *arg, int val);
715 bool is_valid_limit (const char *arg);
716
717 // The number of currently active variables and clauses can be queried by
718 // these functions. Variables become active if a clause is added with it.
719 // They become inactive if they are eliminated or fixed at the root level
720 // Clauses become inactive if they are satisfied, subsumed, eliminated.
721 // Redundant clauses are reduced regularly and thus the 'redundant'
722 // function is less useful.
723 //
724 // require (VALID)
725 // ensure (VALID)
726 //
727 int active () const; // Number of active variables.
728 int64_t redundant () const; // Number of active redundant clauses.
729 int64_t irredundant () const; // Number of active irredundant clauses.
730
731 //------------------------------------------------------------------------
732 // This function executes the given number of preprocessing rounds. It is
733 // similar to 'solve' with 'limits ("preprocessing", rounds)' except that
734 // no CDCL nor local search, nor lucky phases are executed. The result
735 // values are also the same: 0=UNKNOWN, 10=SATISFIABLE, 20=UNSATISFIABLE.
736 // As 'solve' it resets current assumptions and limits before returning.
737 // The numbers of rounds should not be negative. If the number of rounds
738 // is zero only clauses are restored (if necessary) and top level unit
739 // propagation is performed, which both take some time.
740 //
741 // require (READY)
742 // ensure (INCONCLUSIVE | SATISFIED | UNSATISFIED)
743 //
744 int simplify (int rounds = 3);
745
746 //------------------------------------------------------------------------
747 // Force termination of 'solve' asynchronously.
748 //
749 // require (SOLVING | READY)
750 // ensure (INCONCLUSIVE ) // actually not immediately (synchronously)
751 //
752 void terminate ();
753
754 //------------------------------------------------------------------------
755
756 // We have the following common reference counting functions, which avoid
757 // to restore clauses but require substantial user guidance. This was the
758 // only way to use inprocessing in incremental SAT solving in Lingeling
759 // (and before in MiniSAT's 'freeze' / 'thaw') and which did not use
760 // automatic clause restoring. In general this is slower than
761 // restoring clauses and should not be used.
762 //
763 // In essence the user freezes variables which potentially are still
764 // needed in clauses added or assumptions used after the next 'solve'
765 // call. As in Lingeling you can freeze a variable multiple times, but
766 // then have to melt it the same number of times again in order to enable
767 // variable eliminating on it etc. The arguments can be literals
768 // (negative indices) but conceptually variables are frozen.
769 //
770 // In the old way of doing things without restore you should not use a
771 // variable incrementally (in 'add' or 'assume'), which was used before
772 // and potentially could have been eliminated in a previous 'solve' call.
773 // This can lead to spurious satisfying assignment. In order to check
774 // this API contract one can use the 'checkfrozen' option. This has the
775 // drawback that restoring clauses implicitly would fail with a fatal
776 // error message even if in principle the solver could just restore
777 // clauses. Thus this option is disabled by default.
778 //
779 // See our SAT'19 paper [FazekasBiereScholl-SAT'19] for more details.
780 //
781 // require (VALID)
782 // ensure (VALID)
783 //
784 bool frozen (int lit) const;
785 void freeze (int lit);
786 void melt (int lit); // Also needs 'require (frozen (lit))'.
787
788 //------------------------------------------------------------------------
789
790 // Root level assigned variables can be queried with this function.
791 // It returns '1' if the literal is implied by the formula, '-1' if its
792 // negation is implied, or '0' if this is unclear at this point.
793 //
794 // require (VALID)
795 // ensure (VALID)
796 //
797 int fixed (int lit) const;
798
799 //------------------------------------------------------------------------
800 // Force the default decision phase of a variable to a certain value.
801 //
802 void phase (int lit);
803 void unphase (int lit);
804
805 //------------------------------------------------------------------------
806
807 // Enables clausal proof tracing in DRAT format and returns 'true' if
808 // successfully opened for writing. Writing proofs has to be enabled
809 // before calling 'solve', 'add' and 'dimacs', that is in state
810 // 'CONFIGURING'. Otherwise only partial proofs would be written.
811 //
812 // require (CONFIGURING)
813 // ensure (CONFIGURING)
814 //
815 bool trace_proof (FILE *file, const char *name); // Write DRAT proof.
816 bool trace_proof (const char *path); // Open & write proof.
817
818 // Flushing the proof trace file eventually calls 'fflush' on the actual
819 // file or pipe and thus if this function returns all the proof steps
820 // should have been written (with the same guarantees as 'fflush').
821 //
822 // The additional optional argument forces to print the number of addition
823 // and deletion steps in the proof even if the verbosity level is zero but
824 // not if quiet is set as well. The default for the stand-alone solver is
825 // to print this information (in the 'closing proof' section) but for API
826 // usage of the library we want to stay silent unless explicitly requested
827 // or verbosity is non-zero (and as explained quiet is not set).
828 //
829 // This function can be called multiple times.
830 //
831 // require (VALID)
832 // ensure (VALID)
833 //
834 void flush_proof_trace (bool print = false);
835
836 // Close proof trace early. Similar to 'flush' we allow the user to
837 // control with 'print' in a more fine-grained way whether statistics
838 // about the size of the written proof file and if compressed on-the-fly
839 // the number of actual bytes written (including deflation percentage) are
840 // printed. Before actually closing (or detaching in case of writing to
841 // '<stdout>') we check whether 'flush_proof_trace' was called since the
842 // last time a proof step (addition or deletion) was traced. If this is
843 // not the case we would call 'flush_proof_trace' with the same 'print'
844 // argument.
845 //
846 // require (VALID)
847 // ensure (VALID)
848 //
849 void close_proof_trace (bool print = false);
850
851 // Enables clausal proof tracing with or without antecedents using
852 // the Tracer interface defined in 'tracer.hpp'
853 //
854 // InternalTracer, StatTracer and FileTracer for internal use
855 //
856 // require (CONFIGURING)
857 // ensure (CONFIGURING)
858 //
859 void connect_proof_tracer (Tracer *tracer, bool antecedents,
860 bool finalize_clauses = false);
861 void connect_proof_tracer (InternalTracer *tracer, bool antecedents,
862 bool finalize_clauses = false);
863 void connect_proof_tracer (StatTracer *tracer, bool antecedents,
864 bool finalize_clauses = false);
865 void connect_proof_tracer (FileTracer *tracer, bool antecedents,
866 bool finalize_clauses = false);
867
868 // Triggers the conclusion of incremental proofs.
869 // if the solver is SATISFIED it will trigger extend ()
870 // and give the model to the proof tracer through conclude_sat ()
871 // if the solver is UNSATISFIED it will trigger failing ()
872 // which will learn new clauses as explained below:
873 // In case of failed assumptions will provide a core negated
874 // as a clause through the proof tracer interface.
875 // With a failing constraint these can be multiple clauses.
876 // Then it will trigger a conclude_unsat event with the id(s)
877 // of the newly learnt clauses or the id of the global conflict.
878 // In case the solver is in UNKNOWN, it will collect the currently
879 // entrailed literals and add them to the proof.
880 //
881 // require (SATISFIED || UNSATISFIED || UNKNOWN)
882 // ensure (SATISFIED || UNSATISFIED || UNKNOWN)
883 //
884 void conclude ();
885
886 // Disconnect proof tracer. If this is not done before deleting
887 // the tracer will be deleted. Returns true if successful.
888 //
889 // require (VALID)
890 // ensure (VALID)
891 //
892 bool disconnect_proof_tracer (Tracer *tracer);
893 bool disconnect_proof_tracer (StatTracer *tracer);
894 bool disconnect_proof_tracer (FileTracer *tracer);
895
896 //------------------------------------------------------------------------
897
898 static void usage (); // print usage information for long options
899
900 static void configurations (); // print configuration usage options
901
902 // require (!DELETING)
903 // ensure (!DELETING)
904 //
905 void statistics (); // print statistics
906 void resources (); // print resource usage (time and memory)
907
908 // require (VALID)
909 // ensure (VALID)
910 //
911 void options (); // print current option and value list
912
913 //------------------------------------------------------------------------
914 // Traverse irredundant clauses or the extension stack in reverse order.
915 //
916 // The return value is false if traversal is aborted early due to one of
917 // the visitor functions returning false. See description of the
918 // iterators below for more details on how to use these functions.
919 //
920 // require (VALID)
921 // ensure (VALID)
922 //
923 bool traverse_clauses (ClauseIterator &) const;
926
927 //------------------------------------------------------------------------
928 // Files with explicit path argument support compressed input and output
929 // if appropriate helper functions 'gzip' etc. are available. They are
930 // called through opening a pipe to an external command.
931 //
932 // If the 'strict' argument is zero then the number of variables and
933 // clauses specified in the DIMACS headers are ignored, i.e., the header
934 // 'p cnf 0 0' is always legal. If the 'strict' argument is larger '1'
935 // strict formatting of the header is required, i.e., single spaces
936 // everywhere and no trailing white space.
937 //
938 // Returns zero if successful and otherwise an error message.
939 //
940 // require (VALID)
941 // ensure (VALID)
942 //
943 const char *read_dimacs (FILE *file, const char *name, int &vars,
944 int strict = 1);
945
946 const char *read_dimacs (const char *path, int &vars, int strict = 1);
947
948 // The following routines work the same way but parse both DIMACS and
949 // INCCNF files (with 'p inccnf' header and 'a <cube>' lines). If the
950 // parser finds and 'p inccnf' header or cubes then '*incremental' is set
951 // to true and the cubes are stored in the given vector (each cube
952 // terminated by a zero).
953
954 const char *read_dimacs (FILE *file, const char *name, int &vars,
955 int strict, bool &incremental,
956 std::vector<int> &cubes);
957
958 const char *read_dimacs (const char *path, int &vars, int strict,
959 bool &incremental, std::vector<int> &cubes);
960
961 //------------------------------------------------------------------------
962 // Write current irredundant clauses and all derived unit clauses
963 // to a file in DIMACS format. Clauses on the extension stack are
964 // not included, nor any redundant clauses.
965 //
966 // The 'min_max_var' parameter gives a lower bound on the number '<vars>'
967 // of variables used in the DIMACS 'p cnf <vars> ...' header.
968 //
969 // Returns zero if successful and otherwise an error message.
970 //
971 // require (VALID)
972 // ensure (VALID)
973 //
974 const char *write_dimacs (const char *path, int min_max_var = 0);
975
976 // The extension stack for reconstruction a solution can be written too.
977 //
978 const char *write_extension (const char *path);
979
980 // Print build configuration to a file with prefix 'c '. If the file
981 // is '<stdout>' or '<stderr>' then terminal color codes might be used.
982 //
983 static void build (FILE *file, const char *prefix = "c ");
984
985private:
986 //==== start of state ====================================================
987
988 // The solver is in the state ADDING if either the current clause or the
989 // constraint (or both) is not yet terminated.
990 bool adding_clause;
991 bool adding_constraint;
992
993 State _state; // API states as discussed above.
994
995 /*----------------------------------------------------------------------*/
996
997 // The 'Solver' class is a 'facade' object for 'External'. It exposes the
998 // public API of 'External' but hides everything else (except for the some
999 // private functions). It is supposed to make it easier to understand the
1000 // API and use the solver through the API.
1001
1002 // This approach has the benefit of decoupling this header file from all
1003 // internal data structures, which is particularly useful if the rest of
1004 // the source is not available. For instance if only a CaDiCaL library is
1005 // installed in a system, then only this header file has to be installed
1006 // too, and still allows to compile and link against the library.
1007
1008 /*----------------------------------------------------------------------*/
1009
1010 // More precisely the CaDiCaL code is split into three layers:
1011 //
1012 // Solver: facade object providing the actual API of the solver
1013 // External: communication layer between 'Solver' and 'Internal'
1014 // Internal: the actual solver code
1015 //
1016 // The 'External' and 'Internal' layers are declared and implemented in
1017 // the corresponding '{external,internal}.{hpp,cpp}' files (as expected),
1018 // while the 'Solver' facade class is defined in 'cadical.hpp' (here) but
1019 // implemented in 'solver.cpp'. The reason for this naming mismatch is,
1020 // that we want to use 'cadical.hpp' for the library header (this header
1021 // file) and call the binary of the stand alone SAT also 'cadical', which
1022 // is more naturally implemented in 'cadical.cpp'.
1023 //
1024 // Separating 'External' from 'Internal' also allows us to map external
1025 // literals to internal literals, which is useful with many fixed or
1026 // eliminated variables (during 'compact' the internal variable range is
1027 // reduced and external variables are remapped). Such an approach is also
1028 // necessary, if we want to use extended resolution in the future (such as
1029 // bounded variable addition).
1030 //
1031 Internal *internal; // Hidden internal solver.
1032 External *external; // Hidden API to internal solver mapping.
1033
1034 friend class Testing; // Access to 'internal' for testing only!
1035
1036#ifndef CADICAL_NTRACING
1037 // The API calls to the solver can be traced by setting the environment
1038 // variable 'CADICAL_API_TRACE' to point to the path of a file to which
1039 // API calls are written. The same format is used which 'mobical' can
1040 // read, execute and also shrink through delta debugging.
1041 //
1042 // The environment variable is read in the constructor and the trace is
1043 // opened for writing and then closed again in the destructor.
1044 //
1045 // Alternatively one case use 'trace_api_calls'. Both
1046 //
1047 bool close_trace_api_file; // Close file if owned by solver it.
1048 FILE *trace_api_file; // Also acts as flag that we are tracing.
1049
1050 static bool tracing_api_through_environment;
1051
1052 //===== end of state ====================================================
1053
1054 void trace_api_call (const char *) const;
1055 void trace_api_call (const char *, int) const;
1056 void trace_api_call (const char *, const char *) const;
1057 void trace_api_call (const char *, const char *, int) const;
1058#endif
1059
1060 void transition_to_steady_state ();
1061
1062 //------------------------------------------------------------------------
1063 // Used in the stand alone solver application 'App' and the model based
1064 // tester 'Mobical'. So only these two classes need direct access to the
1065 // otherwise more application specific functions listed here together with
1066 // the internal DIMACS parser.
1067
1068 friend class App;
1069 friend class Mobical;
1070 friend class Parser;
1071
1072 // Read solution in competition format for debugging and testing.
1073 //
1074 // require (VALID)
1075 // ensure (VALID)
1076 //
1077 const char *read_solution (const char *path);
1078
1079 // Cross-compilation with 'MinGW' needs some work-around for 'printf'
1080 // style printing of 64-bit numbers including warning messages. The
1081 // followings lines are copies of similar code in 'inttypes.hpp' but we
1082 // want to keep the 'cadical.hpp' header file stand-alone.
1083
1084#ifndef PRINTF_FORMAT
1085#ifdef __MINGW32__
1086#define __USE_MINGW_ANSI_STDIO 1
1087#define PRINTF_FORMAT __MINGW_PRINTF_FORMAT
1088#else
1089#define PRINTF_FORMAT printf
1090#endif
1091#endif
1092
1093 // This gives warning messages for wrong 'printf' style format string
1094 // usage. Apparently (on 'gcc 9' at least) the first argument is 'this'
1095 // here.
1096 //
1097 // TODO: support for other compilers (beside 'gcc' and 'clang').
1098
1099 /*
1100#define CADICAL_ATTRIBUTE_FORMAT(FORMAT_POSITION, \
1101 VARIADIC_ARGUMENT_POSITION) \
1102 __attribute__ ((format (PRINTF_FORMAT, FORMAT_POSITION, \
1103 VARIADIC_ARGUMENT_POSITION)))
1104 */
1105#define CADICAL_ATTRIBUTE_FORMAT(FORMAT_POSITION, VARIADIC_ARGUMENT_POSITION)
1106
1107 // Messages in a common style.
1108 //
1109 // require (VALID | DELETING)
1110 // ensure (VALID | DELETING)
1111 //
1112 void section (const char *); // print section header
1113 void message (const char *, ...) // ordinary message
1115
1116 void message (); // empty line - only prefix
1117 void error (const char *, ...) // produce error message
1119
1120 // Explicit verbose level ('section' and 'message' use '0').
1121 //
1122 // require (VALID | DELETING)
1123 // ensure (VALID | DELETING)
1124 //
1125 void verbose (int level, const char *, ...)
1127
1128 // Factoring out common code to both 'read_dimacs' functions above.
1129 //
1130 // require (VALID)
1131 // ensure (VALID)
1132 //
1133 const char *read_dimacs (File *, int &, int strict, bool *incremental = 0,
1134 std::vector<int> * = 0);
1135
1136 // Factored out common code for 'solve', 'simplify' and 'lookahead'.
1137 //
1138 int call_external_solve_and_check_results (bool preprocess_only);
1139
1140 //------------------------------------------------------------------------
1141 // Print DIMACS file to '<stdout>' for debugging and testing purposes,
1142 // including derived units and assumptions. Since it will print in terms
1143 // of internal literals it is otherwise not really useful. To write a
1144 // DIMACS formula in terms of external variables use 'write_dimacs'.
1145 //
1146 // require (!INITIALIZING)
1147 // ensure (!INITIALIZING)
1148 //
1149 void dump_cnf ();
1150 friend struct DumpCall; // Mobical calls 'dump_cnf' in 'DumpCall::execute'
1151
1152 /*----------------------------------------------------------------------*/
1153
1154 // Used in mobical to test external propagation internally.
1155 // These functions should not be called for any other purposes.
1156 //
1157 ExternalPropagator *get_propagator ();
1158 bool observed (int lit);
1159 bool is_witness (int lit);
1160
1161 friend struct LemmaCall;
1162 friend struct ObserveCall;
1163 friend struct DisconnectCall;
1164 friend class MockPropagator;
1165};
1166
1167/*========================================================================*/
1168
1169// Connected terminators are checked for termination regularly. If the
1170// 'terminate' function of the terminator returns true the solver is
1171// terminated synchronously as soon it calls this function.
1172
1174public:
1175 virtual ~Terminator () {}
1176 virtual bool terminate () = 0;
1177};
1178
1179// Connected learners which can be used to export learned clauses.
1180// The 'learning' can check the size of the learn clause and only if it
1181// returns true then the individual literals of the learned clause are given
1182// to the learn through 'learn' one by one terminated by a zero literal.
1183
1184class Learner {
1185public:
1186 virtual ~Learner () {}
1187 virtual bool learning (int size) = 0;
1188 virtual void learn (int lit) = 0;
1189};
1190
1191// Connected listener gets notified whenever the truth value of a variable
1192// is fixed (for example during inprocessing or due to some derived unit
1193// clauses).
1194
1196public:
1198
1199 virtual void notify_fixed_assignment (int) = 0;
1200};
1201
1202/*------------------------------------------------------------------------*/
1203
1204// Allows to connect an external propagator to propagate values to variables
1205// with an external clause as a reason or to learn new clauses during the
1206// CDCL loop (without restart).
1207
1209
1210public:
1211 bool is_lazy = false; // lazy propagator only checks complete assignments
1213 false; // Reason external clauses can be deleted
1214
1216
1217 // Notify the propagator about assignments to observed variables.
1218 // The notification is not necessarily eager. It usually happens before
1219 // the call of propagator callbacks and when a driving clause is leading
1220 // to an assignment.
1221 //
1222 // virtual void notify_assignment (int lit, bool is_fixed) = 0;
1223 virtual void notify_assignment (const std::vector<int> &lits) = 0;
1224 virtual void notify_new_decision_level () = 0;
1225 virtual void notify_backtrack (size_t new_level) = 0;
1226
1227 // Check by the external propagator the found complete solution (after
1228 // solution reconstruction). If it returns false, the propagator should
1229 // provide an external clause during the next callback or introduce new
1230 // observed variables during this callback.
1231 //
1232 virtual bool cb_check_found_model (const std::vector<int> &model) = 0;
1233
1234 // Ask the external propagator for the next decision literal. If it
1235 // returns 0, the solver makes its own choice.
1236 //
1237 virtual int cb_decide () { return 0; };
1238
1239 // Ask the external propagator if there is an external propagation to make
1240 // under the current assignment. It returns either a literal to be
1241 // propagated or 0, indicating that there is no external propagation under
1242 // the current assignment.
1243 //
1244 virtual int cb_propagate () { return 0; };
1245
1246 // Ask the external propagator for the reason clause of a previous
1247 // external propagation step (done by cb_propagate). The clause must be
1248 // added literal-by-literal closed with a 0. Further, the clause must
1249 // contain the propagated literal.
1250 //
1251 // The clause will be learned as an Irredundant Non-Forgettable Clause
1252 // (see below at 'cb_has_external_clause' more details about it).
1253 //
1254 virtual int cb_add_reason_clause_lit (int propagated_lit) {
1255 (void) propagated_lit;
1256 return 0;
1257 };
1258
1259 // The following two functions are used to add external clauses to the
1260 // solver during the CDCL loop. The external clause is added
1261 // literal-by-literal and learned by the solver as an irredundant
1262 // (original) input clause. The clause can be arbitrary, but if it is
1263 // root-satisfied or tautology, the solver will ignore it without learning
1264 // it. Root-falsified literals are eagerly removed from the clause.
1265 // Falsified clauses trigger conflict analysis, propagating clauses
1266 // trigger propagation. In case chrono is 0, the solver backtracks to
1267 // propagate the new literal on the right decision level, otherwise it
1268 // potentially will be an out-of-order assignment on the current level.
1269 // Unit clauses always (unless root-satisfied, see above) trigger
1270 // backtracking (independently from the value of the chrono option and
1271 // independently from being falsified or satisfied or unassigned) to level
1272 // 0. Empty clause (or root falsified clause, see above) makes the problem
1273 // unsat and stops the search immediately. A literal 0 must close the
1274 // clause.
1275 //
1276 // The external propagator indicates that there is a clause to add.
1277 // The parameter of the function allows the user to indicate that how
1278 // 'forgettable' is the external clause. Forgettable clauses are allowed
1279 // to be removed by the SAT solver during clause database reduction.
1280 // However, it is up to the solver to decide when actually the clause is
1281 // deleted. For example, unit clauses, even forgettable ones, will not be
1282 // deleted. In case the clause is not 'forgettable' (the parameter is
1283 // false), the solver considers the clause to be irredundant.
1284 //
1285 // In case the solver produces incremental proofs, these external clauses
1286 // are added to the proof during solving at real-time, i.e., the proof
1287 // checker can ignore them until that point (so added as input clause, but
1288 // input after the query line).
1289 //
1290 // Reason clauses of external propagation steps are assumed to be
1291 // forgettable, parameter 'reason_forgettable' can be used to change it.
1292 //
1293 // Currently, every external clause is expected to be over observed
1294 // (therefore frozen) variables, hence no tainting or restore steps
1295 // are performed upon their addition. This will be changed in later
1296 // versions probably.
1297 //
1298 virtual bool cb_has_external_clause (bool &is_forgettable) = 0;
1299
1300 // The actual function called to add the external clause.
1301 //
1302 virtual int cb_add_external_clause_lit () = 0;
1303};
1304
1305/*------------------------------------------------------------------------*/
1306
1307// Allows to traverse all remaining irredundant clauses. Satisfied and
1308// eliminated clauses are not included, nor any derived units unless such
1309// a unit literal is frozen. Falsified literals are skipped. If the solver
1310// is inconsistent only the empty clause is traversed.
1311//
1312// If 'clause' returns false traversal aborts early.
1313
1315public:
1316 virtual ~ClauseIterator () {}
1317 virtual bool clause (const std::vector<int> &) = 0;
1318};
1319
1320/*------------------------------------------------------------------------*/
1321
1322// Allows to traverse all clauses on the extension stack together with their
1323// witness cubes. If the solver is inconsistent, i.e., an empty clause is
1324// found and the formula is unsatisfiable, then nothing is traversed.
1325//
1326// The clauses traversed in 'traverse_clauses' together with the clauses on
1327// the extension stack are logically equivalent to the original clauses.
1328// See our SAT'19 paper for more details.
1329//
1330// The witness literals can be used to extend and fix an assignment on the
1331// remaining clauses to satisfy the clauses on the extension stack too.
1332//
1333// All derived units of non-frozen variables are included too.
1334//
1335// If 'witness' returns false traversal aborts early.
1336
1338public:
1339 virtual ~WitnessIterator () {}
1340 virtual bool witness (const std::vector<int> &clause,
1341 const std::vector<int> &witness,
1342 int64_t id = 0) = 0;
1343};
1344
1345/*------------------------------------------------------------------------*/
1346
1347} // namespace CaDiCaL
1348
1350
1351#endif
#define ABC_NAMESPACE_CXX_HEADER_START
#define ABC_NAMESPACE_CXX_HEADER_END
#define CADICAL_ATTRIBUTE_FORMAT(FORMAT_POSITION, VARIADIC_ARGUMENT_POSITION)
Definition cadical.hpp:1105
virtual bool clause(const std::vector< int > &)=0
virtual void notify_backtrack(size_t new_level)=0
virtual bool cb_has_external_clause(bool &is_forgettable)=0
virtual int cb_add_reason_clause_lit(int propagated_lit)
Definition cadical.hpp:1254
virtual void notify_new_decision_level()=0
virtual int cb_add_external_clause_lit()=0
virtual bool cb_check_found_model(const std::vector< int > &model)=0
virtual void notify_assignment(const std::vector< int > &lits)=0
virtual void notify_fixed_assignment(int)=0
virtual void learn(int lit)=0
virtual bool learning(int size)=0
virtual ~Learner()
Definition cadical.hpp:1186
bool failed(int lit)
void connect_learner(Learner *learner)
const char * write_dimacs(const char *path, int min_max_var=0)
void unphase(int lit)
bool set_long_option(const char *arg)
void add_observed_var(int var)
const char * read_dimacs(const char *path, int &vars, int strict, bool &incremental, std::vector< int > &cubes)
bool is_decision(int lit)
int fixed(int lit) const
void connect_external_propagator(ExternalPropagator *propagator)
void implied(std::vector< int > &implicants)
void force_backtrack(size_t new_level)
CubesWithStatus generate_cubes(int, int min_depth=0)
bool is_valid_limit(const char *arg)
const State & state() const
Definition cadical.hpp:529
void add(int lit)
friend class Testing
Definition cadical.hpp:1034
static bool is_valid_option(const char *name)
void flush_proof_trace(bool print=false)
friend class App
Definition cadical.hpp:1068
static void usage()
friend struct LemmaCall
Definition cadical.hpp:1161
bool limit(const char *arg, int val)
void connect_proof_tracer(Tracer *tracer, bool antecedents, bool finalize_clauses=false)
int64_t redundant() const
void remove_observed_var(int var)
bool disconnect_proof_tracer(Tracer *tracer)
int64_t irredundant() const
void prefix(const char *verbose_message_prefix)
static bool is_preprocessing_option(const char *name)
void close_proof_trace(bool print=false)
void connect_fixed_listener(FixedAssignmentListener *fixed_listener)
const char * write_extension(const char *path)
int status() const
Definition cadical.hpp:534
const char * read_dimacs(FILE *file, const char *name, int &vars, int strict, bool &incremental, std::vector< int > &cubes)
void disconnect_external_propagator()
friend class Mobical
Definition cadical.hpp:1069
static void build(FILE *file, const char *prefix="c ")
void freeze(int lit)
int get(const char *name)
void optimize(int val)
friend class MockPropagator
Definition cadical.hpp:1164
bool configure(const char *)
int reserve_difference(int number_of_vars)
static const char * signature()
friend class Parser
Definition cadical.hpp:1070
static bool is_valid_long_option(const char *arg)
bool set(const char *name, int val)
void reserve(int min_max_var)
void constrain(int lit)
static void configurations()
bool flip(int lit)
bool trace_proof(FILE *file, const char *name)
static const char * version()
void assume(int lit)
bool frozen(int lit) const
void connect_terminator(Terminator *terminator)
friend struct ObserveCall
Definition cadical.hpp:1162
bool traverse_witnesses_backward(WitnessIterator &) const
void copy(Solver &other) const
static bool is_valid_configuration(const char *)
friend struct DisconnectCall
Definition cadical.hpp:1163
bool flippable(int lit)
friend struct DumpCall
Definition cadical.hpp:1150
bool traverse_clauses(ClauseIterator &) const
bool traverse_witnesses_forward(WitnessIterator &) const
void disconnect_fixed_listener()
const char * read_dimacs(FILE *file, const char *name, int &vars, int strict=1)
virtual ~Terminator()
Definition cadical.hpp:1175
virtual bool terminate()=0
virtual bool witness(const std::vector< int > &clause, const std::vector< int > &witness, int64_t id=0)=0
pcover simplify()
char * name
Definition main.h:24
@ SATISFIED
Definition cadical.hpp:192
@ INITIALIZING
Definition cadical.hpp:187
@ INCONCLUSIVE
Definition cadical.hpp:195
@ UNSATISFIED
Definition cadical.hpp:193
@ CONFIGURING
Definition cadical.hpp:188
@ UNKNOWN
Definition cadical.hpp:31
@ UNSATISFIABLE
Definition cadical.hpp:30
@ SATISFIABLE
Definition cadical.hpp:29
struct clause_t clause
STRUCTURE DEFINITIONS ///.
Definition satClause.h:48
int lit
Definition satVec.h:130
std::vector< std::vector< int > > cubes
Definition cadical.hpp:519
Definition file.h:23
#define const
Definition zconf.h:196