3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-10 19:27:06 +00:00
z3/lib/assertion_stack.h
Leonardo de Moura e9eab22e5c Z3 sources
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2012-10-02 11:35:25 -07:00

142 lines
5.8 KiB
C++

/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
assertion_stack.h
Abstract:
It should be viewed as the "goal" object for incremental solvers.
The main difference is the support of push/pop operations. Like a
goal, an assertion_stack contains expressions, their proofs (if
proof generation is enabled), and dependencies (if unsat core
generation is enabled).
The assertions on the stack are grouped by scope levels. Scoped
levels are created using push, and removed using pop.
Assertions may be "committed". Whenever a push is executed, all
"uncommitted" assertions are automatically committed.
Only uncommitted assertions can be simplified/reduced.
An assertion set has a limited model converter that only supports
definitions (for variable/function elimination) and filters (for fresh
symbols introduced by tactics).
Some tactics support assertion_stacks and can be applied to them.
However, a tactic can only access the assertions on the top level.
The assertion stack also informs the tactic which declarations
can't be eliminated since they occur in the already committed part.
Author:
Leonardo de Moura (leonardo) 2012-02-17
Revision History:
--*/
#ifndef _ASSERTION_STACK_H_
#define _ASSERTION_STACK_H_
#include"ast.h"
#include"model.h"
#include"expr_substitution.h"
#include"macro_substitution.h"
class assertion_stack {
ast_manager & m_manager;
unsigned m_ref_count;
bool m_models_enabled; // model generation is enabled.
bool m_proofs_enabled; // proof production is enabled. m_manager.proofs_enabled() must be true if m_proofs_enabled == true
bool m_core_enabled; // unsat core extraction is enabled.
bool m_inconsistent;
ptr_vector<expr> m_forms;
ptr_vector<proof> m_proofs;
ptr_vector<expr_dependency> m_deps;
unsigned m_form_qhead; // position of first uncommitted assertion
unsigned m_mc_qhead;
// Set of declarations that can't be eliminated
obj_hashtable<func_decl> m_forbidden_set;
func_decl_ref_vector m_forbidden;
// Limited model converter support, it supports only extensions
// and filters.
// It should be viewed as combination of extension_model_converter and
// filter_model_converter for goals.
expr_substitution m_csubst; // substitution for eliminated constants
macro_substitution m_fsubst; // substitution for eliminated functions
// Model converter is just a sequence of tagged pointers.
// Tag 0 (extension) func_decl was eliminated, and its definition is in m_vsubst or m_fsubst.
// Tag 1 (filter) func_decl was introduced by tactic, and must be removed from model.
ptr_vector<func_decl> m_mc;
struct scope {
unsigned m_forms_lim;
unsigned m_forbidden_vars_lim;
unsigned m_mc_lim;
bool m_inconsistent_old;
};
svector<scope> m_scopes;
void init(bool proofs_enabled, bool models_enabled, bool core_enabled);
void expand(expr * f, proof * pr, expr_dependency * dep, expr_ref & new_f, proof_ref & new_pr, expr_dependency_ref & new_dep);
void push_back(expr * f, proof * pr, expr_dependency * d);
void quick_process(bool save_first, expr * & f, expr_dependency * d);
void process_and(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr);
void process_not_or(bool save_first, app * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr);
void slow_process(bool save_first, expr * f, proof * pr, expr_dependency * d, expr_ref & out_f, proof_ref & out_pr);
void slow_process(expr * f, proof * pr, expr_dependency * d);
public:
assertion_stack(ast_manager & m, bool models_enabled = true, bool core_enabled = true);
assertion_stack(ast_manager & m, bool proofs_enabled, bool models_enabled, bool core_enabled);
~assertion_stack();
void reset();
void inc_ref() { ++m_ref_count; }
void dec_ref() { --m_ref_count; if (m_ref_count == 0) dealloc(this); }
ast_manager & m() const { return m_manager; }
bool models_enabled() const { return m_models_enabled; }
bool proofs_enabled() const { return m_proofs_enabled; }
bool unsat_core_enabled() const { return m_core_enabled; }
bool inconsistent() const { return m_inconsistent; }
unsigned size() const { return m_forms.size(); }
unsigned qhead() const { return m_form_qhead; }
expr * form(unsigned i) const { return m_forms[i]; }
proof * pr(unsigned i) const { return proofs_enabled() ? static_cast<proof*>(m_proofs[i]) : 0; }
expr_dependency * dep(unsigned i) const { return unsat_core_enabled() ? m_deps[i] : 0; }
void assert_expr(expr * f, proof * pr, expr_dependency * d);
void assert_expr(expr * f) {
assert_expr(f, proofs_enabled() ? m().mk_asserted(f) : 0, 0);
}
void update(unsigned i, expr * f, proof * pr = 0, expr_dependency * dep = 0);
void expand_and_update(unsigned i, expr * f, proof * pr = 0, expr_dependency * d = 0);
void commit();
void push();
void pop(unsigned num_scopes);
unsigned scope_lvl() const { return m_scopes.size(); }
bool is_well_sorted() const;
bool is_forbidden(func_decl * f) const { return m_forbidden_set.contains(f); }
void add_filter(func_decl * f) const;
void add_definition(app * c, expr * def, proof * pr, expr_dependency * dep);
void add_definition(func_decl * f, quantifier * q, proof * pr, expr_dependency * dep);
void convert(model_ref & m);
void display(std::ostream & out) const;
};
#endif