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:
parent
d847a28589
commit
4630373a97
9 changed files with 297 additions and 72 deletions
|
|
@ -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) {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue