mirror of
https://github.com/Z3Prover/z3
synced 2025-10-30 11:12:28 +00:00
adding factory for model initialization
This commit is contained in:
parent
9e79fe0a51
commit
981c7d27ea
3 changed files with 96 additions and 12 deletions
|
|
@ -173,11 +173,8 @@ void finite_set_decl_plugin::get_sort_names(svector<builtin_name>& sort_names, s
|
|||
expr * finite_set_decl_plugin::get_some_value(sort * s) {
|
||||
if (is_finite_set(s)) {
|
||||
// Return empty set for the given sort
|
||||
sort* element_sort = get_element_sort(s);
|
||||
if (element_sort) {
|
||||
parameter param(element_sort);
|
||||
return m_manager->mk_app(m_family_id, OP_FINITE_SET_EMPTY, 1, ¶m, 0, nullptr);
|
||||
}
|
||||
parameter param(s);
|
||||
return m_manager->mk_app(m_family_id, OP_FINITE_SET_EMPTY, 1, ¶m, 0, nullptr);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,16 @@ namespace smt {
|
|||
m_axioms.set_add_clause(add_clause_fn);
|
||||
}
|
||||
|
||||
theory_finite_set::~theory_finite_set() {
|
||||
reset_set_members();
|
||||
}
|
||||
|
||||
void theory_finite_set::reset_set_members() {
|
||||
for (auto [k, s] : m_set_members)
|
||||
dealloc(s);
|
||||
m_set_members.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Boolean atomic formulas for finite sets are one of:
|
||||
* (set.in x S)
|
||||
|
|
@ -108,6 +118,12 @@ namespace smt {
|
|||
return true;
|
||||
}
|
||||
|
||||
void theory_finite_set::apply_sort_cnstr(enode* n, sort* s) {
|
||||
SASSERT(u.is_finite_set(s));
|
||||
if (!is_attached_to_var(n))
|
||||
ctx.attach_th_var(n, this, mk_var(n));
|
||||
}
|
||||
|
||||
void theory_finite_set::new_eq_eh(theory_var v1, theory_var v2) {
|
||||
TRACE(finite_set, tout << "new_eq_eh: v" << v1 << " = v" << v2 << "\n";);
|
||||
// When two sets are equal, propagate membership constraints
|
||||
|
|
@ -275,15 +291,78 @@ namespace smt {
|
|||
TRACE(finite_set, tout << "init_model\n";);
|
||||
// Model generation will use default interpretation for sets
|
||||
// The model will be constructed based on the membership literals that are true
|
||||
m_factory = alloc(finite_set_value_factory, m, u.get_family_id(), mg.get_model());
|
||||
mg.register_factory(m_factory);
|
||||
collect_members();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void theory_finite_set::collect_members() {
|
||||
// This method can be used to collect all elements that are members of sets
|
||||
// and ensure that the model factory has values for them.
|
||||
// For now, we rely on the default model construction.
|
||||
reset_set_members();
|
||||
for (auto x : m_elements) {
|
||||
if (!ctx.is_relevant(x))
|
||||
continue;
|
||||
x = x->get_root();
|
||||
// TODO: use marking of x to avoid duplicate work
|
||||
for (auto p : enode::parents(x)) {
|
||||
if (!ctx.is_relevant(p))
|
||||
continue;
|
||||
if (!u.is_in(p->get_expr()))
|
||||
continue;
|
||||
if (ctx.get_assignment(p->get_expr()) != l_true)
|
||||
continue;
|
||||
enode *elem = nullptr, *set = nullptr;
|
||||
set = p->get_arg(1)->get_root();
|
||||
elem = p->get_arg(0)->get_root();
|
||||
if (elem != x)
|
||||
continue;
|
||||
if (!m_set_members.contains(set))
|
||||
m_set_members.insert(set, alloc(obj_hashtable<enode>));
|
||||
m_set_members.find(set)->insert(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct finite_set_value_proc : model_value_proc {
|
||||
finite_set_util& u;
|
||||
sort *s = nullptr;
|
||||
obj_hashtable<enode>* m_elements = nullptr;
|
||||
|
||||
finite_set_value_proc(finite_set_util& u, sort* s, obj_hashtable<enode>* elements) :
|
||||
u(u), s(s),
|
||||
m_elements(elements) {}
|
||||
|
||||
void get_dependencies(buffer<model_value_dependency> &result) override {
|
||||
if (!m_elements)
|
||||
return;
|
||||
for (auto v : *m_elements)
|
||||
result.push_back(model_value_dependency(v));
|
||||
}
|
||||
|
||||
app *mk_value(model_generator &mg, expr_ref_vector const &values) override {
|
||||
SASSERT(values.size() == m_elements->size());
|
||||
if (values.empty())
|
||||
return u.mk_empty(s);
|
||||
SASSERT(m_elements);
|
||||
app *r = nullptr;
|
||||
for (auto v : values) {
|
||||
app *e = u.mk_singleton(v);
|
||||
r = r ? u.mk_union(r, e) : e;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
model_value_proc * theory_finite_set::mk_value(enode * n, model_generator & mg) {
|
||||
TRACE(finite_set, tout << "mk_value: " << mk_pp(n->get_expr(), m) << "\n";);
|
||||
|
||||
// For now, return nullptr to use default model construction
|
||||
// A complete implementation would construct explicit set values
|
||||
// based on true membership literals
|
||||
return nullptr;
|
||||
TRACE(finite_set, tout << "mk_value: " << mk_pp(n->get_expr(), m) << "\n";);
|
||||
obj_hashtable<enode>*elements = nullptr;
|
||||
sort *s = n->get_expr()->get_sort();
|
||||
m_set_members.find(n->get_root(), elements);
|
||||
return alloc(finite_set_value_proc, u, s, elements);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ theory_finite_set.cpp.
|
|||
#include "ast/rewriter/finite_set_axioms.h"
|
||||
#include "util/obj_pair_hashtable.h"
|
||||
#include "smt/smt_theory.h"
|
||||
#include "model/finite_set_value_factory.h"
|
||||
|
||||
namespace smt {
|
||||
class theory_finite_set : public theory {
|
||||
|
|
@ -99,6 +100,8 @@ namespace smt {
|
|||
obj_hashtable<enode> m_elements; // set of all 'x' where there is an 'x in S' atom
|
||||
vector<expr_ref_vector> m_lemmas;
|
||||
obj_pair_hashtable<expr, expr> m_lemma_exprs;
|
||||
finite_set_value_factory *m_factory = nullptr;
|
||||
obj_map<enode, obj_hashtable<enode> *> m_set_members;
|
||||
|
||||
protected:
|
||||
// Override relevant methods from smt::theory
|
||||
|
|
@ -106,6 +109,7 @@ namespace smt {
|
|||
bool internalize_term(app * term) override;
|
||||
void new_eq_eh(theory_var v1, theory_var v2) override;
|
||||
void new_diseq_eh(theory_var v1, theory_var v2) override;
|
||||
void apply_sort_cnstr(enode *n, sort *s) override;
|
||||
final_check_status final_check_eh() override;
|
||||
|
||||
theory * mk_fresh(context * new_ctx) override;
|
||||
|
|
@ -125,10 +129,14 @@ namespace smt {
|
|||
void add_immediate_axioms(app *atom);
|
||||
bool add_membership_axioms();
|
||||
bool add_extensionality_axioms();
|
||||
|
||||
// model construction
|
||||
void collect_members();
|
||||
void reset_set_members();
|
||||
|
||||
public:
|
||||
theory_finite_set(context& ctx);
|
||||
~theory_finite_set() override {}
|
||||
~theory_finite_set() override;
|
||||
};
|
||||
|
||||
} // namespace smt
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue