mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 09:35:32 +00:00
working on named assertions support
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
230382d4c9
commit
d545f187f8
10 changed files with 223 additions and 96 deletions
|
@ -95,6 +95,13 @@ public:
|
|||
*/
|
||||
virtual void assert_expr(expr * t) = 0;
|
||||
|
||||
/**
|
||||
\brief Add a new formula \c t to the assertion stack, and "tag" it with \c a.
|
||||
The propositional varialbe \c a is used to track the use of \c t in a proof
|
||||
of unsatisfiability.
|
||||
*/
|
||||
virtual void assert_expr(expr * t, expr * a) = 0;
|
||||
|
||||
/**
|
||||
\brief Create a backtracking point.
|
||||
*/
|
||||
|
|
96
src/solver/solver_na2as.cpp
Normal file
96
src/solver/solver_na2as.cpp
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
solver_na2as.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Solver that implements "named" assertions using assumptions (aka answer literals).
|
||||
That is, a named assertion assert_expr(t, a) is mapped into
|
||||
a implies t
|
||||
and 'a' is used as an extra assumption for check_sat.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2012-11-02
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"solver_na2as.h"
|
||||
|
||||
solver_na2as::solver_na2as() {
|
||||
m_manager = 0;
|
||||
}
|
||||
|
||||
solver_na2as::~solver_na2as() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void solver_na2as::assert_expr(expr * t, expr * a) {
|
||||
SASSERT(m_manager != 0);
|
||||
expr * new_t = m_manager->mk_implies(a, t);
|
||||
m_manager->inc_ref(a);
|
||||
m_assumptions.push_back(a);
|
||||
assert_expr(new_t);
|
||||
}
|
||||
|
||||
void solver_na2as::init(ast_manager & m, symbol const & logic) {
|
||||
SASSERT(m_assumptions.empty());
|
||||
m_manager = &m;
|
||||
init_core(m, logic);
|
||||
}
|
||||
|
||||
struct append_assumptions {
|
||||
ptr_vector<expr> & m_assumptions;
|
||||
unsigned m_old_sz;
|
||||
append_assumptions(ptr_vector<expr> & _m_assumptions,
|
||||
unsigned num_assumptions,
|
||||
expr * const * assumptions):
|
||||
m_assumptions(_m_assumptions) {
|
||||
m_old_sz = m_assumptions.size();
|
||||
m_assumptions.append(num_assumptions, assumptions);
|
||||
}
|
||||
|
||||
~append_assumptions() {
|
||||
m_assumptions.shrink(m_old_sz);
|
||||
}
|
||||
};
|
||||
|
||||
lbool solver_na2as::check_sat(unsigned num_assumptions, expr * const * assumptions) {
|
||||
append_assumptions app(m_assumptions, num_assumptions, assumptions);
|
||||
return check_sat_core(num_assumptions, assumptions);
|
||||
}
|
||||
|
||||
void solver_na2as::push() {
|
||||
m_scopes.push_back(m_assumptions.size());
|
||||
push_core();
|
||||
}
|
||||
|
||||
void solver_na2as::pop(unsigned n) {
|
||||
pop_core(n);
|
||||
unsigned lvl = m_scopes.size();
|
||||
SASSERT(n <= lvl);
|
||||
unsigned new_lvl = lvl - n;
|
||||
restore_assumptions(m_scopes[new_lvl]);
|
||||
m_scopes.shrink(new_lvl);
|
||||
}
|
||||
|
||||
void solver_na2as::restore_assumptions(unsigned old_sz) {
|
||||
SASSERT(m_manager);
|
||||
for (unsigned i = old_sz; i < m_assumptions.size(); i++) {
|
||||
m_manager->dec_ref(m_assumptions[i]);
|
||||
}
|
||||
m_assumptions.shrink(old_sz);
|
||||
}
|
||||
|
||||
unsigned solver_na2as::get_scope_level() const {
|
||||
return m_scopes.size();
|
||||
}
|
||||
|
||||
void solver_na2as::reset() {
|
||||
if (m_manager)
|
||||
restore_assumptions(0);
|
||||
}
|
55
src/solver/solver_na2as.h
Normal file
55
src/solver/solver_na2as.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
solver_na2as.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Solver that implements "named" assertions using assumptions (aka answer literals).
|
||||
That is, a named assertion assert_expr(t, a) is mapped into
|
||||
a implies t
|
||||
and 'a' is used as an extra assumption for check_sat.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2012-11-02
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _SOLVER_NA2AS_H_
|
||||
#define _SOLVER_NA2AS_H_
|
||||
|
||||
#include"solver.h"
|
||||
|
||||
class solver_na2as : public solver {
|
||||
ast_manager * m_manager;
|
||||
ptr_vector<expr> m_assumptions;
|
||||
unsigned_vector m_scopes;
|
||||
void restore_assumptions(unsigned old_sz);
|
||||
public:
|
||||
solver_na2as();
|
||||
virtual ~solver_na2as();
|
||||
|
||||
virtual void assert_expr(expr * t, expr * a);
|
||||
virtual void assert_expr(expr * t) = 0;
|
||||
|
||||
// Subclasses of solver_na2as should redefine the following *_core methods instead of these ones.
|
||||
virtual void init(ast_manager & m, symbol const & logic);
|
||||
virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions);
|
||||
virtual void push();
|
||||
virtual void pop(unsigned n);
|
||||
virtual unsigned get_scope_level() const;
|
||||
virtual void reset();
|
||||
protected:
|
||||
virtual void init_core(ast_manager & m, symbol const & logic) = 0;
|
||||
virtual lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) = 0;
|
||||
virtual void push_core() = 0;
|
||||
virtual void pop_core(unsigned n) = 0;
|
||||
virtual void reset_core() = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -128,7 +128,7 @@ void strategic_solver_core::set_tactic_for(symbol const & logic, tactic_factory
|
|||
m_logic2fct.insert(logic, fct);
|
||||
}
|
||||
|
||||
void strategic_solver_core::init(ast_manager & m, symbol const & logic) {
|
||||
void strategic_solver_core::init_core(ast_manager & m, symbol const & logic) {
|
||||
m_manager = &m;
|
||||
m_logic = logic;
|
||||
if (m_inc_mode) {
|
||||
|
@ -165,7 +165,7 @@ void strategic_solver_core::collect_statistics(statistics & st) const {
|
|||
}
|
||||
}
|
||||
|
||||
void strategic_solver_core::reset() {
|
||||
void strategic_solver_core::reset_core() {
|
||||
m_logic = symbol::null;
|
||||
m_inc_mode = false;
|
||||
m_check_sat_executed = false;
|
||||
|
@ -199,14 +199,14 @@ void strategic_solver_core::assert_expr(expr * t) {
|
|||
}
|
||||
}
|
||||
|
||||
void strategic_solver_core::push() {
|
||||
void strategic_solver_core::push_core() {
|
||||
DEBUG_CODE(m_num_scopes++;);
|
||||
init_inc_solver();
|
||||
if (m_inc_solver)
|
||||
m_inc_solver->push();
|
||||
}
|
||||
|
||||
void strategic_solver_core::pop(unsigned n) {
|
||||
void strategic_solver_core::pop_core(unsigned n) {
|
||||
DEBUG_CODE({
|
||||
SASSERT(n <= m_num_scopes);
|
||||
m_num_scopes -= n;
|
||||
|
@ -216,13 +216,6 @@ void strategic_solver_core::pop(unsigned n) {
|
|||
m_inc_solver->pop(n);
|
||||
}
|
||||
|
||||
unsigned strategic_solver_core::get_scope_level() const {
|
||||
if (m_inc_solver)
|
||||
return m_inc_solver->get_scope_level();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct aux_timeout_eh : public event_handler {
|
||||
solver * m_solver;
|
||||
volatile bool m_canceled;
|
||||
|
@ -278,7 +271,7 @@ lbool strategic_solver_core::check_sat_with_assumptions(unsigned num_assumptions
|
|||
return m_inc_solver->check_sat(num_assumptions, assumptions);
|
||||
}
|
||||
|
||||
lbool strategic_solver_core::check_sat(unsigned num_assumptions, expr * const * assumptions) {
|
||||
lbool strategic_solver_core::check_sat_core(unsigned num_assumptions, expr * const * assumptions) {
|
||||
reset_results();
|
||||
m_check_sat_executed = true;
|
||||
if (num_assumptions > 0 || // assumptions were provided
|
||||
|
@ -427,8 +420,8 @@ void strategic_solver_core::display(std::ostream & out) const {
|
|||
strategic_solver::ctx::ctx(ast_manager & m):m_assertions(m) {
|
||||
}
|
||||
|
||||
void strategic_solver::init(ast_manager & m, symbol const & logic) {
|
||||
strategic_solver_core::init(m, logic);
|
||||
void strategic_solver::init_core(ast_manager & m, symbol const & logic) {
|
||||
strategic_solver_core::init_core(m, logic);
|
||||
m_ctx = alloc(ctx, m);
|
||||
}
|
||||
|
||||
|
@ -449,24 +442,24 @@ void strategic_solver::assert_expr(expr * t) {
|
|||
m_ctx->m_assertions.push_back(t);
|
||||
}
|
||||
|
||||
void strategic_solver::push() {
|
||||
void strategic_solver::push_core() {
|
||||
SASSERT(m_ctx);
|
||||
strategic_solver_core::push();
|
||||
strategic_solver_core::push_core();
|
||||
m_ctx->m_scopes.push_back(m_ctx->m_assertions.size());
|
||||
}
|
||||
|
||||
void strategic_solver::pop(unsigned n) {
|
||||
void strategic_solver::pop_core(unsigned n) {
|
||||
SASSERT(m_ctx);
|
||||
unsigned new_lvl = m_ctx->m_scopes.size() - n;
|
||||
unsigned old_sz = m_ctx->m_scopes[new_lvl];
|
||||
m_ctx->m_assertions.shrink(old_sz);
|
||||
m_ctx->m_scopes.shrink(new_lvl);
|
||||
strategic_solver_core::pop(n);
|
||||
strategic_solver_core::pop_core(n);
|
||||
}
|
||||
|
||||
void strategic_solver::reset() {
|
||||
void strategic_solver::reset_core() {
|
||||
m_ctx = 0;
|
||||
strategic_solver_core::reset();
|
||||
strategic_solver_core::reset_core();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ Notes:
|
|||
#ifndef _STRATEGIC_SOLVER_H_
|
||||
#define _STRATEGIC_SOLVER_H_
|
||||
|
||||
#include"solver.h"
|
||||
#include"solver_na2as.h"
|
||||
#include"tactic.h"
|
||||
|
||||
class progress_callback;
|
||||
|
@ -46,7 +46,7 @@ struct front_end_params;
|
|||
It goes back to non_incremental mode when:
|
||||
- reset is invoked.
|
||||
*/
|
||||
class strategic_solver_core : public solver {
|
||||
class strategic_solver_core : public solver_na2as {
|
||||
public:
|
||||
// Behavior when the incremental solver returns unknown.
|
||||
enum inc_unknown_behavior {
|
||||
|
@ -123,14 +123,13 @@ public:
|
|||
|
||||
virtual void display(std::ostream & out) const;
|
||||
|
||||
virtual void init(ast_manager & m, symbol const & logic);
|
||||
virtual void init_core(ast_manager & m, symbol const & logic);
|
||||
virtual void collect_statistics(statistics & st) const;
|
||||
virtual void reset();
|
||||
virtual void reset_core();
|
||||
virtual void assert_expr(expr * t);
|
||||
virtual void push();
|
||||
virtual void pop(unsigned n);
|
||||
virtual unsigned get_scope_level() const;
|
||||
virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions);
|
||||
virtual void push_core();
|
||||
virtual void pop_core(unsigned n);
|
||||
virtual lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions);
|
||||
virtual void get_unsat_core(ptr_vector<expr> & r);
|
||||
virtual void get_model(model_ref & m);
|
||||
virtual proof * get_proof();
|
||||
|
@ -153,12 +152,12 @@ class strategic_solver : public strategic_solver_core {
|
|||
public:
|
||||
strategic_solver() {}
|
||||
|
||||
virtual void init(ast_manager & m, symbol const & logic);
|
||||
virtual void init_core(ast_manager & m, symbol const & logic);
|
||||
|
||||
virtual void assert_expr(expr * t);
|
||||
virtual void push();
|
||||
virtual void pop(unsigned n);
|
||||
virtual void reset();
|
||||
virtual void push_core();
|
||||
virtual void pop_core(unsigned n);
|
||||
virtual void reset_core();
|
||||
|
||||
virtual unsigned get_num_assertions() const;
|
||||
virtual expr * get_assertion(unsigned idx) const;
|
||||
|
|
|
@ -31,7 +31,7 @@ tactic2solver_core::ctx::ctx(ast_manager & m, symbol const & logic):
|
|||
tactic2solver_core::~tactic2solver_core() {
|
||||
}
|
||||
|
||||
void tactic2solver_core::init(ast_manager & m, symbol const & logic) {
|
||||
void tactic2solver_core::init_core(ast_manager & m, symbol const & logic) {
|
||||
m_ctx = alloc(ctx, m, logic);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ void tactic2solver_core::collect_param_descrs(param_descrs & r) {
|
|||
}
|
||||
}
|
||||
|
||||
void tactic2solver_core::reset() {
|
||||
void tactic2solver_core::reset_core() {
|
||||
SASSERT(m_ctx);
|
||||
m_ctx->m_assertions.reset();
|
||||
m_ctx->m_scopes.reset();
|
||||
|
@ -75,13 +75,13 @@ void tactic2solver_core::assert_expr(expr * t) {
|
|||
m_ctx->m_result = 0;
|
||||
}
|
||||
|
||||
void tactic2solver_core::push() {
|
||||
void tactic2solver_core::push_core() {
|
||||
SASSERT(m_ctx);
|
||||
m_ctx->m_scopes.push_back(m_ctx->m_assertions.size());
|
||||
m_ctx->m_result = 0;
|
||||
}
|
||||
|
||||
void tactic2solver_core::pop(unsigned n) {
|
||||
void tactic2solver_core::pop_core(unsigned n) {
|
||||
SASSERT(m_ctx);
|
||||
unsigned new_lvl = m_ctx->m_scopes.size() - n;
|
||||
unsigned old_sz = m_ctx->m_scopes[new_lvl];
|
||||
|
@ -90,12 +90,7 @@ void tactic2solver_core::pop(unsigned n) {
|
|||
m_ctx->m_result = 0;
|
||||
}
|
||||
|
||||
unsigned tactic2solver_core::get_scope_level() const {
|
||||
SASSERT(m_ctx);
|
||||
return m_ctx->m_scopes.size();
|
||||
}
|
||||
|
||||
lbool tactic2solver_core::check_sat(unsigned num_assumptions, expr * const * assumptions) {
|
||||
lbool tactic2solver_core::check_sat_core(unsigned num_assumptions, expr * const * assumptions) {
|
||||
SASSERT(m_ctx);
|
||||
ast_manager & m = m_ctx->m();
|
||||
params_ref p = m_params;
|
||||
|
|
|
@ -22,7 +22,7 @@ Notes:
|
|||
#ifndef _TACTIC2SOLVER_H_
|
||||
#define _TACTIC2SOLVER_H_
|
||||
|
||||
#include"solver.h"
|
||||
#include"solver_na2as.h"
|
||||
#include"tactic.h"
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,7 @@ Notes:
|
|||
option for applications trying to solve many easy queries that a
|
||||
similar to each other.
|
||||
*/
|
||||
class tactic2solver_core : public solver {
|
||||
class tactic2solver_core : public solver_na2as {
|
||||
struct ctx {
|
||||
symbol m_logic;
|
||||
expr_ref_vector m_assertions;
|
||||
|
@ -63,13 +63,13 @@ public:
|
|||
virtual void set_produce_models(bool f) { m_produce_models = f; }
|
||||
virtual void set_produce_unsat_cores(bool f) { m_produce_unsat_cores = f; }
|
||||
|
||||
virtual void init(ast_manager & m, symbol const & logic);
|
||||
virtual void reset();
|
||||
virtual void assert_expr(expr * t);
|
||||
virtual void push();
|
||||
virtual void pop(unsigned n);
|
||||
virtual unsigned get_scope_level() const;
|
||||
virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions);
|
||||
|
||||
virtual void init_core(ast_manager & m, symbol const & logic);
|
||||
virtual void reset_core();
|
||||
virtual void push_core();
|
||||
virtual void pop_core(unsigned n);
|
||||
virtual lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions);
|
||||
|
||||
virtual void set_cancel(bool f);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue