Skip to content

Commit c1be0a3

Browse files
Decision procedure interface for solving with contexts/assumptions
Provides combined push/pop + assumptions interface
1 parent 89d349b commit c1be0a3

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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

Comments
 (0)