mirror of
https://github.com/Z3Prover/z3
synced 2025-05-02 13:27:01 +00:00
bug fixes and cleanup in projection functions
spacer would drop variables of sorts not handled by main loop. - projection with witness needs to disable qel style preprocessing to ensure witnesses are returned. - add euf plugin to handle uninterpreted sorts (and then uninterpreted functions)
This commit is contained in:
parent
0cf2b5f515
commit
eee96ec312
12 changed files with 249 additions and 108 deletions
|
@ -6,6 +6,7 @@ z3_add_component(mbp
|
|||
mbp_basic_tg.cpp
|
||||
mbp_datatypes.cpp
|
||||
mbp_dt_tg.cpp
|
||||
mbp_euf.cpp
|
||||
mbp_qel.cpp
|
||||
mbp_qel_util.cpp
|
||||
mbp_plugin.cpp
|
||||
|
|
|
@ -27,7 +27,7 @@ class mbp_basic_tg : public mbp_tg_plugin {
|
|||
struct impl;
|
||||
impl *m_impl;
|
||||
|
||||
public:
|
||||
public:
|
||||
mbp_basic_tg(ast_manager &man, mbp::term_graph &tg, model &mdl,
|
||||
obj_hashtable<app> &vars_set, expr_sparse_mark &seen);
|
||||
// iterate through all terms in m_tg and apply all basic MBP rules once
|
||||
|
|
85
src/qe/mbp/mbp_euf.cpp
Normal file
85
src/qe/mbp/mbp_euf.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*++
|
||||
Copyright (c) 2025 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "ast/ast_util.h"
|
||||
#include "ast/for_each_expr.h"
|
||||
#include "qe/mbp/mbp_euf.h"
|
||||
#include "qe/mbp/mbp_term_graph.h"
|
||||
|
||||
namespace mbp {
|
||||
euf_project_plugin::euf_project_plugin(ast_manager& m): project_plugin(m) {
|
||||
|
||||
}
|
||||
|
||||
euf_project_plugin::~euf_project_plugin() {
|
||||
|
||||
}
|
||||
|
||||
bool euf_project_plugin::project1(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) {
|
||||
return false;
|
||||
}
|
||||
|
||||
family_id euf_project_plugin::get_family_id() {
|
||||
return basic_family_id;
|
||||
}
|
||||
|
||||
bool euf_project_plugin::operator()(model& model, app_ref_vector& vars, expr_ref_vector& lits) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool euf_project_plugin::project(model& model, app_ref_vector& vars, expr_ref_vector& lits, vector<def>& defs) {
|
||||
if (vars.empty())
|
||||
return false;
|
||||
flatten_and(lits);
|
||||
expr_mark var_set;
|
||||
auto is_pure = [&](expr_mark& var_set, expr* v) {
|
||||
return all_of(subterms::all(expr_ref(v, m)), [&](expr* w) { return !var_set.is_marked(w); });
|
||||
};
|
||||
for (auto v : vars)
|
||||
var_set.mark(v, true);
|
||||
unsigned has_def = false;
|
||||
#if 1
|
||||
// solve trivial equations
|
||||
for (auto e : lits) {
|
||||
expr* x = nullptr, *y = nullptr;
|
||||
if (m.is_eq(e, x, y) && var_set.is_marked(x) && is_pure(var_set, y)) {
|
||||
vars.erase(to_app(x));
|
||||
defs.push_back({ expr_ref(x, m), expr_ref(y, m) });
|
||||
has_def = true;
|
||||
}
|
||||
else if (m.is_eq(e, y, x) && var_set.is_marked(x) && is_pure(var_set, y)) {
|
||||
vars.erase(to_app(x));
|
||||
defs.push_back({ expr_ref(x, m), expr_ref(y, m) });
|
||||
has_def = true;
|
||||
}
|
||||
}
|
||||
if (has_def)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
// check if there is a variable of uninterp sort
|
||||
if (all_of(vars, [&](expr* v) { return !m.is_uninterp(v->get_sort()); }))
|
||||
return has_def;
|
||||
|
||||
term_graph tg(m);
|
||||
tg.add_lits(lits);
|
||||
for (auto v : vars)
|
||||
if (m.is_uninterp(v->get_sort()))
|
||||
tg.add_var(v);
|
||||
|
||||
//
|
||||
// now what:
|
||||
/// walk all subterms of lits.
|
||||
// push in partitions by value.
|
||||
// add equations from model
|
||||
// compute repr from tg.
|
||||
//
|
||||
|
||||
|
||||
return has_def;
|
||||
}
|
||||
|
||||
}
|
30
src/qe/mbp/mbp_euf.h
Normal file
30
src/qe/mbp/mbp_euf.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2025 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "model/model.h"
|
||||
#include "qe/mbp/mbp_plugin.h"
|
||||
|
||||
namespace mbp {
|
||||
|
||||
class euf_project_plugin : public project_plugin {
|
||||
public:
|
||||
euf_project_plugin(ast_manager& m);
|
||||
~euf_project_plugin() override;
|
||||
|
||||
bool project1(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) override;
|
||||
bool solve(model& model, app_ref_vector& vars, expr_ref_vector& lits) override { return false; }
|
||||
family_id get_family_id() override;
|
||||
bool operator()(model& model, app_ref_vector& vars, expr_ref_vector& lits) override;
|
||||
bool project(model& model, app_ref_vector& vars, expr_ref_vector& lits, vector<def>& defs) override;
|
||||
void saturate(model& model, func_decl_ref_vector const& shared, expr_ref_vector& lits) override { UNREACHABLE(); }
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
|
@ -205,7 +205,7 @@ namespace mbp {
|
|||
else
|
||||
extract_bools(eval, fmls, i, fml, true);
|
||||
}
|
||||
TRACE("qe", tout << fmls << "\n";);
|
||||
TRACE("qe", tout << "fmls: " << fmls << "\n";);
|
||||
}
|
||||
|
||||
void project_plugin::extract_bools(model_evaluator& eval, expr_ref_vector& fmls, unsigned idx, expr* fml, bool is_true) {
|
||||
|
|
|
@ -21,6 +21,7 @@ Revision History:
|
|||
#pragma once
|
||||
|
||||
#include "ast/ast.h"
|
||||
#include "ast/ast_pp.h"
|
||||
#include "util/params.h"
|
||||
#include "model/model.h"
|
||||
#include "math/simplex/model_based_opt.h"
|
||||
|
@ -32,11 +33,12 @@ namespace mbp {
|
|||
|
||||
struct def {
|
||||
expr_ref var, term;
|
||||
def(const expr_ref& v, expr_ref& t): var(v), term(t) {}
|
||||
};
|
||||
|
||||
class project_plugin {
|
||||
protected:
|
||||
ast_manager& m;
|
||||
private:
|
||||
expr_mark m_visited;
|
||||
ptr_vector<expr> m_to_visit;
|
||||
expr_mark m_bool_visited;
|
||||
|
@ -110,3 +112,6 @@ namespace mbp {
|
|||
};
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, mbp::def const& d) {
|
||||
return out << d.var << " -> " << d.term << "\n";
|
||||
}
|
||||
|
|
|
@ -1018,8 +1018,7 @@ void term_graph::to_lits(expr_ref_vector &lits, bool all_equalities,
|
|||
void term_graph::to_lits_qe_lite(expr_ref_vector &lits,
|
||||
std::function<bool(expr *)> *non_core) {
|
||||
DEBUG_CODE(for (auto t : m_terms) SASSERT(t->get_repr()););
|
||||
DEBUG_CODE(for (auto t
|
||||
: m_terms)
|
||||
DEBUG_CODE(for (auto t : m_terms)
|
||||
SASSERT(!t->is_cgr() || t->get_repr()->is_cgr()););
|
||||
is_non_core not_in_core(non_core);
|
||||
check_pred contains_nc(not_in_core, m, false);
|
||||
|
|
|
@ -32,10 +32,10 @@ Notes:
|
|||
#include "util/plugin_manager.h"
|
||||
|
||||
namespace mbp {
|
||||
namespace is_ground_ns {
|
||||
struct proc;
|
||||
struct found;
|
||||
} // namespace is_ground_ns
|
||||
namespace is_ground_ns {
|
||||
struct proc;
|
||||
struct found;
|
||||
} // namespace is_ground_ns
|
||||
class term;
|
||||
|
||||
class term_graph {
|
||||
|
@ -246,16 +246,16 @@ private:
|
|||
bool makes_cycle(term *t);
|
||||
};
|
||||
|
||||
namespace is_ground_ns {
|
||||
struct found {};
|
||||
struct proc {
|
||||
term_graph::is_variable_proc &m_is_var;
|
||||
proc(term_graph::is_variable_proc &is_var) : m_is_var(is_var) {}
|
||||
void operator()(var *n) const {}
|
||||
void operator()(app const *n) const {
|
||||
if (m_is_var.contains(n->get_decl())) throw found();
|
||||
}
|
||||
void operator()(quantifier *n) const {}
|
||||
};
|
||||
} // namespace is_ground_ns
|
||||
namespace is_ground_ns {
|
||||
struct found {};
|
||||
struct proc {
|
||||
term_graph::is_variable_proc &m_is_var;
|
||||
proc(term_graph::is_variable_proc &is_var) : m_is_var(is_var) {}
|
||||
void operator()(var *n) const {}
|
||||
void operator()(app const *n) const {
|
||||
if (m_is_var.contains(n->get_decl())) throw found();
|
||||
}
|
||||
void operator()(quantifier *n) const {}
|
||||
};
|
||||
} // namespace is_ground_ns
|
||||
} // namespace mbp
|
||||
|
|
|
@ -23,12 +23,12 @@ Revision History:
|
|||
#include "util/obj_hashtable.h"
|
||||
|
||||
class mbp_tg_plugin {
|
||||
public:
|
||||
// iterate through all terms in m_tg and apply all theory MBP rules once
|
||||
// returns true if any rules were applied
|
||||
virtual bool apply() { return false; };
|
||||
virtual ~mbp_tg_plugin() = default;
|
||||
virtual void use_model() { };
|
||||
virtual void get_new_vars(app_ref_vector*&) { };
|
||||
virtual family_id get_family_id() const { return null_family_id; };
|
||||
public:
|
||||
// iterate through all terms in m_tg and apply all theory MBP rules once
|
||||
// returns true if any rules were applied
|
||||
virtual bool apply() { return false; };
|
||||
virtual ~mbp_tg_plugin() = default;
|
||||
virtual void use_model() { };
|
||||
virtual void get_new_vars(app_ref_vector*&) { };
|
||||
virtual family_id get_family_id() const { return null_family_id; };
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue