mirror of
https://github.com/Z3Prover/z3
synced 2025-08-08 04:01:22 +00:00
172 lines
6.3 KiB
C++
172 lines
6.3 KiB
C++
/*++
|
|
Copyright (c) 2022 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dependent_expr_state.h
|
|
|
|
Abstract:
|
|
|
|
abstraction for simplification of dependent expression states.
|
|
A dependent_expr_state is an interface to a set of dependent expressions.
|
|
Dependent expressions are formulas together with a set of dependencies that are coarse grained
|
|
proof hints or justifications for them. Input assumptions can be self-justified.
|
|
|
|
The dependent_expr_simplifier implements main services:
|
|
- push, pop - that scope the local state
|
|
- reduce - to process formulas in a dependent_expr_state between the current value of m_qhead and the size()
|
|
of the depdenent_expr_state
|
|
|
|
A dependent expr_simplifier can be used to:
|
|
- to build a tactic
|
|
- for incremental pre-processing
|
|
|
|
Author:
|
|
|
|
Nikolaj Bjorner (nbjorner) 2022-11-2.
|
|
|
|
--*/
|
|
|
|
#pragma once
|
|
|
|
#include "util/trail.h"
|
|
#include "util/statistics.h"
|
|
#include "util/params.h"
|
|
#include "util/z3_exception.h"
|
|
#include "ast/converters/model_converter.h"
|
|
#include "ast/simplifiers/dependent_expr.h"
|
|
#include "ast/simplifiers/model_reconstruction_trail.h"
|
|
|
|
|
|
/**
|
|
abstract interface to state updated by simplifiers.
|
|
*/
|
|
class dependent_expr_state {
|
|
unsigned m_qhead = 0;
|
|
bool m_suffix_frozen = false;
|
|
unsigned m_num_recfun = 0, m_num_lambdas = 0;
|
|
lbool m_has_quantifiers = l_undef;
|
|
ast_mark m_frozen;
|
|
func_decl_ref_vector m_frozen_trail;
|
|
void freeze_prefix();
|
|
void freeze_recfun();
|
|
void freeze_lambda();
|
|
void freeze_terms(expr* term, bool only_as_array, ast_mark& visited);
|
|
void freeze(func_decl* f);
|
|
struct thaw : public trail {
|
|
unsigned sz;
|
|
dependent_expr_state& st;
|
|
thaw(dependent_expr_state& st) : sz(st.m_frozen_trail.size()), st(st) {}
|
|
void undo() override {
|
|
for (unsigned i = st.m_frozen_trail.size(); i-- > sz; )
|
|
st.m_frozen.mark(st.m_frozen_trail.get(i), false);
|
|
st.m_frozen_trail.shrink(sz);
|
|
}
|
|
};
|
|
public:
|
|
dependent_expr_state(ast_manager& m) : m_frozen_trail(m) {}
|
|
virtual ~dependent_expr_state() {}
|
|
unsigned qhead() const { return m_qhead; }
|
|
virtual unsigned qtail() const = 0;
|
|
virtual dependent_expr const& operator[](unsigned i) = 0;
|
|
virtual void update(unsigned i, dependent_expr const& j) = 0;
|
|
virtual void add(dependent_expr const& j) = 0;
|
|
virtual bool inconsistent() = 0;
|
|
virtual model_reconstruction_trail& model_trail() = 0;
|
|
virtual void flatten_suffix() {}
|
|
virtual bool updated() = 0;
|
|
virtual void reset_updated() = 0;
|
|
|
|
trail_stack m_trail;
|
|
void push() {
|
|
m_trail.push_scope();
|
|
m_trail.push(value_trail(m_qhead));
|
|
m_trail.push(thaw(*this));
|
|
}
|
|
void pop(unsigned n) { m_trail.pop_scope(n); }
|
|
|
|
void advance_qhead() { freeze_prefix(); m_suffix_frozen = false; m_has_quantifiers = l_undef; m_qhead = qtail(); }
|
|
unsigned num_exprs();
|
|
|
|
/**
|
|
* Freeze internal functions
|
|
*/
|
|
void freeze(expr* term);
|
|
void freeze(expr_ref_vector const& terms) { for (expr* t : terms) freeze(t); }
|
|
bool frozen(func_decl* f) const { return m_frozen.is_marked(f); }
|
|
bool frozen(expr* f) const { return is_app(f) && m_frozen.is_marked(to_app(f)->get_decl()); }
|
|
void freeze_suffix();
|
|
|
|
virtual std::ostream& display(std::ostream& out) const { return out; }
|
|
|
|
bool has_quantifiers();
|
|
};
|
|
|
|
class default_dependent_expr_state : public dependent_expr_state {
|
|
public:
|
|
default_dependent_expr_state(ast_manager& m): dependent_expr_state(m) {}
|
|
unsigned qtail() const override { return 0; }
|
|
dependent_expr const& operator[](unsigned i) override { throw default_exception("unexpected access"); }
|
|
void update(unsigned i, dependent_expr const& j) override { throw default_exception("unexpected update"); }
|
|
void add(dependent_expr const& j) override { throw default_exception("unexpected addition"); }
|
|
bool inconsistent() override { return false; }
|
|
model_reconstruction_trail& model_trail() override { throw default_exception("unexpected access to model reconstruction"); }
|
|
bool updated() override { return false; }
|
|
void reset_updated() override {}
|
|
|
|
};
|
|
|
|
inline std::ostream& operator<<(std::ostream& out, dependent_expr_state& st) {
|
|
return st.display(out);
|
|
}
|
|
|
|
/**
|
|
Shared interface of simplifiers.
|
|
*/
|
|
class dependent_expr_simplifier {
|
|
protected:
|
|
ast_manager& m;
|
|
dependent_expr_state& m_fmls;
|
|
trail_stack& m_trail;
|
|
|
|
unsigned num_scopes() const { return m_trail.get_num_scopes(); }
|
|
|
|
unsigned qhead() const { return m_fmls.qhead(); }
|
|
unsigned qtail() const { return m_fmls.qtail(); }
|
|
struct iterator {
|
|
dependent_expr_simplifier& s;
|
|
unsigned m_index, m_end;
|
|
iterator(dependent_expr_simplifier& s, unsigned i, unsigned end) : s(s), m_index(i), m_end(end) {}
|
|
bool operator!=(iterator const& other) const { return m_index != other.m_index; }
|
|
iterator& operator++() { if (!s.m.inc() || s.m_fmls.inconsistent() || m_index >= s.qtail()) m_index = m_end; else ++m_index; return *this; }
|
|
unsigned operator*() const { return m_index; }
|
|
};
|
|
|
|
struct index_set {
|
|
dependent_expr_simplifier& s;
|
|
iterator begin() { return iterator(s, s.qhead(), s.qtail()); }
|
|
iterator end() { return iterator(s, s.qtail(), s.qtail()); }
|
|
index_set(dependent_expr_simplifier& s) : s(s) {}
|
|
};
|
|
|
|
index_set indices() { return index_set(*this); }
|
|
|
|
proof* mp(proof* a, proof* b) { return (a && b) ? m.mk_modus_ponens(a, b) : nullptr; }
|
|
proof* tr(proof* a, proof* b) { return m.mk_transitivity(a, b); }
|
|
public:
|
|
dependent_expr_simplifier(ast_manager& m, dependent_expr_state& s) : m(m), m_fmls(s), m_trail(s.m_trail) {}
|
|
virtual ~dependent_expr_simplifier() {}
|
|
virtual char const* name() const = 0;
|
|
virtual void push() { }
|
|
virtual void pop(unsigned n) { }
|
|
virtual void reduce() = 0;
|
|
virtual void collect_statistics(statistics& st) const {}
|
|
virtual void reset_statistics() {}
|
|
virtual void updt_params(params_ref const& p) {}
|
|
virtual void collect_param_descrs(param_descrs& r) {}
|
|
virtual bool supports_proofs() const { return false; }
|
|
ast_manager& get_manager() { return m; }
|
|
dependent_expr_state& get_fmls() { return m_fmls; }
|
|
};
|
|
|
|
typedef std::function<dependent_expr_simplifier*(ast_manager&, const params_ref&, dependent_expr_state& s)> simplifier_factory;
|