|
| 1 | +/*******************************************************************\ |
| 2 | +
|
| 3 | +Module: Decision procedure with incremental solving with contexts |
| 4 | + and assumptions |
| 5 | +
|
| 6 | +Author: Peter Schrammel |
| 7 | +
|
| 8 | +\*******************************************************************/ |
| 9 | + |
| 10 | +/// \file |
| 11 | +/// Decision procedure with incremental solving with contexts |
| 12 | +/// and assumptions |
| 13 | +/// |
| 14 | +/// Normally, solvers allow you only to add new conjuncts to the |
| 15 | +/// formula, but not to remove parts of the formula once added. |
| 16 | +/// |
| 17 | +/// Solvers that offer pushing/popping of contexts or |
| 18 | +/// 'solving under assumptions' offer some ways to emulate |
| 19 | +/// removing parts of the formula. |
| 20 | +/// |
| 21 | +/// Example 1: push/pop contexts: |
| 22 | +/// \code{.cpp} |
| 23 | +/// dp.set_to_true(a); // added permanently |
| 24 | +/// resultt result = dp(); // solves formula 'a' |
| 25 | +/// stack_decision_procedure.set_to_true(b); // added permanently |
| 26 | +/// resultt result = dp(); // solves 'a && b' |
| 27 | +/// dp.push(); |
| 28 | +/// dp.set_to_true(c); // added inside a context: we can remove it later |
| 29 | +/// resultt result = dp(); // solves 'a && b && c' |
| 30 | +/// dp.pop(); // 'removes' c |
| 31 | +/// dp.push(); |
| 32 | +/// dp.set_to_true(d); // added inside a context: we can remove it later |
| 33 | +/// resultt result = dp(); // solves 'a && b && d' |
| 34 | +/// \endcode |
| 35 | +/// |
| 36 | +/// Example 2: solving under assumptions: |
| 37 | +/// \code{.cpp} |
| 38 | +/// dp.set_to_true(a); // added permanently |
| 39 | +/// resultt result = dp(); // solves formula 'a' |
| 40 | +/// h1 = dp.handle(c); |
| 41 | +/// h2 = dp.handle(d) |
| 42 | +/// dp.push({h1, h2}); |
| 43 | +/// resultt result = dp(); // solves formula 'a && c && d' |
| 44 | +/// dp.pop(); // clear assumptions h1, h2 |
| 45 | +/// h1 = dp.handle(not_exprt(c)); // get negated handle for 'c' |
| 46 | +/// dp.push({h1, h2}); |
| 47 | +/// resultt result = dp(); // solves formula 'a && !c && d' |
| 48 | +/// \endcode |
| 49 | + |
| 50 | +#ifndef CPROVER_SOLVERS_STACK_DECISION_PROCEDURE_H |
| 51 | +#define CPROVER_SOLVERS_STACK_DECISION_PROCEDURE_H |
| 52 | + |
| 53 | +#include <vector> |
| 54 | + |
| 55 | +#include "decision_procedure.h" |
| 56 | + |
| 57 | +class stack_decision_proceduret : public decision_proceduret |
| 58 | +{ |
| 59 | +public: |
| 60 | + /// Pushes a new context on the stack that consists of the given |
| 61 | + /// (possibly empty vector of) \p assumptions. |
| 62 | + /// This context becomes a child context nested in the current context. |
| 63 | + /// An assumption is usually obtained by calling |
| 64 | + /// `decision_proceduret::handle`. Thus it can be a Boolean expression or |
| 65 | + /// something more solver-specific such as `literal_exprt`. |
| 66 | + /// An empty vector of assumptions counts as an element on the stack |
| 67 | + /// (and therefore needs to be popped), but has no effect beyond that. |
| 68 | + virtual void push(const std::vector<exprt> &assumptions) = 0; |
| 69 | + |
| 70 | + /// Push a new context on the stack |
| 71 | + /// This context becomes a child context nested in the current context. |
| 72 | + virtual void push() = 0; |
| 73 | + |
| 74 | + /// Pop whatever is on top of the stack. |
| 75 | + /// Popping from the empty stack results in an invariant violation. |
| 76 | + virtual void pop() = 0; |
| 77 | + |
| 78 | + virtual ~stack_decision_proceduret() = default; |
| 79 | +}; |
| 80 | + |
| 81 | +#endif // CPROVER_SOLVERS_STACK_DECISION_PROCEDURE_H |
0 commit comments