3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-07-03 22:06:11 +00:00

add finite sets to datatype recursion, delay initialize finite_set plugin, fix bugs in are_distinct and equality simplification

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2025-10-27 10:37:19 +01:00
parent d847a28589
commit 4630373a97
9 changed files with 297 additions and 72 deletions

View file

@ -335,6 +335,7 @@ namespace smt {
for (unsigned i = 0; i < num_args; i++) {
enode * arg = e->get_arg(i);
sort * s = arg->get_sort();
sort *e_sort = nullptr;
if (m_autil.is_array(s) && m_util.is_datatype(get_array_range(s))) {
app_ref def(m_autil.mk_default(arg->get_expr()), m);
if (!ctx.e_internalized(def)) {
@ -342,6 +343,13 @@ namespace smt {
}
arg = ctx.get_enode(def);
}
if (m_fsutil.is_finite_set(s, e_sort) && m_util.is_datatype(e_sort)) {
app_ref def(m_fsutil.mk_empty(s), m);
if (!ctx.e_internalized(def)) {
ctx.internalize(def, false);
}
arg = ctx.get_enode(def);
}
if (!m_util.is_datatype(s) && !m_sutil.is_seq(s))
continue;
if (is_attached_to_var(arg))
@ -532,8 +540,9 @@ namespace smt {
found = true;
}
sort * s = arg->get_sort();
if (m_autil.is_array(s) && m_util.is_datatype(get_array_range(s))) {
for (enode* aarg : get_array_args(arg)) {
sort *se = nullptr;
auto add_args = [&](ptr_vector<enode> const &args) {
for (enode *aarg : args) {
if (aarg->get_root() == child->get_root()) {
if (aarg != child) {
m_used_eqs.push_back(enode_pair(aarg, child));
@ -541,17 +550,16 @@ namespace smt {
found = true;
}
}
};
if (m_autil.is_array(s) && m_util.is_datatype(get_array_range(s))) {
add_args(get_array_args(arg));
}
if (m_fsutil.is_finite_set(s, se) && m_util.is_datatype(se)) {
add_args(get_finite_set_args(arg));
}
sort* se = nullptr;
if (m_sutil.is_seq(s, se) && m_util.is_datatype(se)) {
enode* sibling;
for (enode* aarg : get_seq_args(arg, sibling)) {
if (aarg->get_root() == child->get_root()) {
if (aarg != child)
m_used_eqs.push_back(enode_pair(aarg, child));
found = true;
}
}
enode *sibling = nullptr;
add_args(get_seq_args(arg, sibling));
if (sibling && sibling != arg)
m_used_eqs.push_back(enode_pair(arg, sibling));
@ -640,6 +648,11 @@ namespace smt {
return true;
}
}
else if (m_fsutil.is_finite_set(s, se) && m_util.is_datatype(se)) {
for (enode *aarg : get_finite_set_args(arg))
if (process_arg(aarg))
return true;
}
else if (m_autil.is_array(s) && m_util.is_datatype(get_array_range(s))) {
for (enode* aarg : get_array_args(arg))
if (process_arg(aarg))
@ -649,6 +662,33 @@ namespace smt {
return false;
}
ptr_vector<enode> const &theory_datatype::get_finite_set_args(enode *n) {
m_args.reset();
m_todo.reset();
auto add_todo = [&](enode *n) {
if (!n->is_marked()) {
n->set_mark();
m_todo.push_back(n);
}
};
add_todo(n);
for (unsigned i = 0; i < m_todo.size(); ++i) {
enode *n = m_todo[i];
expr *e = n->get_expr();
if (m_fsutil.is_singleton(e))
m_args.push_back(n->get_arg(0));
else if (m_fsutil.is_union(e))
for (auto k : enode::args(n))
add_todo(k);
}
for (enode *n : m_todo)
n->unset_mark();
return m_args;
}
ptr_vector<enode> const& theory_datatype::get_seq_args(enode* n, enode*& sibling) {
m_args.reset();
m_todo.reset();
@ -762,6 +802,7 @@ namespace smt {
m_util(m),
m_autil(m),
m_sutil(m),
m_fsutil(m),
m_find(*this) {
}

View file

@ -21,6 +21,7 @@ Revision History:
#include "util/union_find.h"
#include "ast/array_decl_plugin.h"
#include "ast/seq_decl_plugin.h"
#include "ast/finite_set_decl_plugin.h"
#include "ast/datatype_decl_plugin.h"
#include "model/datatype_factory.h"
#include "smt/smt_theory.h"
@ -48,6 +49,7 @@ namespace smt {
datatype_util m_util;
array_util m_autil;
seq_util m_sutil;
finite_set_util m_fsutil;
ptr_vector<var_data> m_var_data;
th_union_find m_find;
trail_stack m_trail_stack;
@ -95,6 +97,7 @@ namespace smt {
ptr_vector<enode> m_args, m_todo;
ptr_vector<enode> const& get_array_args(enode* n);
ptr_vector<enode> const& get_seq_args(enode* n, enode*& sibling);
ptr_vector<enode> const& get_finite_set_args(enode *n);
// class for managing state of final_check
class final_check_st {

View file

@ -690,6 +690,7 @@ namespace smt {
continue;
out << "watch[" << i << "] := " << m_clauses.watch[i] << "\n";
}
m_cardinality_solver.display(out);
}
void theory_finite_set::init_model(model_generator & mg) {

View file

@ -65,7 +65,7 @@ namespace smt {
expr_ref_vector bs(m);
for (auto n : ns) {
std::ostringstream strm;
strm << enode_pp(n, ctx);
strm << "|" << enode_pp(n, ctx) << "|";
symbol name = symbol(strm.str());
expr_ref b(m.mk_const(name, m.mk_bool_sort()), m);
bs.push_back(b);
@ -401,7 +401,7 @@ namespace smt {
return false;
}
std::ostream& theory_finite_set_size::display(std::ostream& out) {
std::ostream& theory_finite_set_size::display(std::ostream& out) const {
if (m_solver)
m_solver->display(out);
return out;

View file

@ -68,6 +68,6 @@ namespace smt {
void add_theory_assumptions(expr_ref_vector &assumptions);
bool should_research(expr_ref_vector &unsat_core);
lbool final_check();
std::ostream &display(std::ostream &out);
std::ostream &display(std::ostream &out) const;
};
}