mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
check for datatype selectors when model validation fails
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
da72911062
commit
cf86e46229
|
@ -1609,12 +1609,16 @@ void cmd_context::set_diagnostic_stream(char const * name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct contains_array_op_proc {
|
struct contains_underspecified_op_proc {
|
||||||
struct found {};
|
struct found {};
|
||||||
family_id m_array_fid;
|
family_id m_array_fid;
|
||||||
contains_array_op_proc(ast_manager & m):m_array_fid(m.mk_family_id("array")) {}
|
datatype_util m_dt;
|
||||||
|
|
||||||
|
contains_underspecified_op_proc(ast_manager & m):m_array_fid(m.mk_family_id("array")), m_dt(m) {}
|
||||||
void operator()(var * n) {}
|
void operator()(var * n) {}
|
||||||
void operator()(app * n) {
|
void operator()(app * n) {
|
||||||
|
if (m_dt.is_accessor(n->get_decl()))
|
||||||
|
throw found();
|
||||||
if (n->get_family_id() != m_array_fid)
|
if (n->get_family_id() != m_array_fid)
|
||||||
return;
|
return;
|
||||||
decl_kind k = n->get_decl_kind();
|
decl_kind k = n->get_decl_kind();
|
||||||
|
@ -1713,7 +1717,7 @@ void cmd_context::validate_model() {
|
||||||
p.set_bool("completion", true);
|
p.set_bool("completion", true);
|
||||||
model_evaluator evaluator(*(md.get()), p);
|
model_evaluator evaluator(*(md.get()), p);
|
||||||
evaluator.set_expand_array_equalities(false);
|
evaluator.set_expand_array_equalities(false);
|
||||||
contains_array_op_proc contains_array(m());
|
contains_underspecified_op_proc contains_underspecified(m());
|
||||||
{
|
{
|
||||||
scoped_rlimit _rlimit(m().limit(), 0);
|
scoped_rlimit _rlimit(m().limit(), 0);
|
||||||
cancel_eh<reslimit> eh(m().limit());
|
cancel_eh<reslimit> eh(m().limit());
|
||||||
|
@ -1739,9 +1743,9 @@ void cmd_context::validate_model() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
for_each_expr(contains_array, r);
|
for_each_expr(contains_underspecified, r);
|
||||||
}
|
}
|
||||||
catch (contains_array_op_proc::found) {
|
catch (contains_underspecified_op_proc::found) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TRACE("model_validate", model_smt2_pp(tout, *this, *(md.get()), 0););
|
TRACE("model_validate", model_smt2_pp(tout, *this, *(md.get()), 0););
|
||||||
|
|
|
@ -38,7 +38,7 @@ expr * datatype_factory::get_some_value(sort * s) {
|
||||||
}
|
}
|
||||||
expr * r = m_manager.mk_app(c, args.size(), args.c_ptr());
|
expr * r = m_manager.mk_app(c, args.size(), args.c_ptr());
|
||||||
register_value(r);
|
register_value(r);
|
||||||
TRACE("datatype_factory", tout << mk_pp(r, m_util.get_manager()) << "\n";);
|
TRACE("datatype", tout << mk_pp(r, m_util.get_manager()) << "\n";);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ expr * datatype_factory::get_some_value(sort * s) {
|
||||||
expr * datatype_factory::get_last_fresh_value(sort * s) {
|
expr * datatype_factory::get_last_fresh_value(sort * s) {
|
||||||
expr * val = 0;
|
expr * val = 0;
|
||||||
if (m_last_fresh_value.find(s, val)) {
|
if (m_last_fresh_value.find(s, val)) {
|
||||||
TRACE("datatype_factory", tout << "cached fresh value: " << mk_pp(val, m_manager) << "\n";);
|
TRACE("datatype", tout << "cached fresh value: " << mk_pp(val, m_manager) << "\n";);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
value_set * set = get_value_set(s);
|
value_set * set = get_value_set(s);
|
||||||
|
@ -68,7 +68,7 @@ bool datatype_factory::is_subterm_of_last_value(app* e) {
|
||||||
}
|
}
|
||||||
contains_app contains(m_manager, e);
|
contains_app contains(m_manager, e);
|
||||||
bool result = contains(last);
|
bool result = contains(last);
|
||||||
TRACE("datatype_factory", tout << mk_pp(e, m_manager) << " in " << mk_pp(last, m_manager) << " " << result << "\n";);
|
TRACE("datatype", tout << mk_pp(e, m_manager) << " in " << mk_pp(last, m_manager) << " " << result << "\n";);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ expr * datatype_factory::get_almost_fresh_value(sort * s) {
|
||||||
m_last_fresh_value.insert(s, new_value);
|
m_last_fresh_value.insert(s, new_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRACE("datatype_factory", tout << "almost fresh: " << mk_pp(new_value, m_manager) << "\n";);
|
TRACE("datatype", tout << "almost fresh: " << mk_pp(new_value, m_manager) << "\n";);
|
||||||
return new_value;
|
return new_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ expr * datatype_factory::get_almost_fresh_value(sort * s) {
|
||||||
|
|
||||||
|
|
||||||
expr * datatype_factory::get_fresh_value(sort * s) {
|
expr * datatype_factory::get_fresh_value(sort * s) {
|
||||||
TRACE("datatype_factory", tout << "generating fresh value for: " << s->get_name() << "\n";);
|
TRACE("datatype", tout << "generating fresh value for: " << s->get_name() << "\n";);
|
||||||
value_set * set = get_value_set(s);
|
value_set * set = get_value_set(s);
|
||||||
// Approach 0)
|
// Approach 0)
|
||||||
// if no value for s was generated so far, then used get_some_value
|
// if no value for s was generated so far, then used get_some_value
|
||||||
|
@ -144,7 +144,7 @@ expr * datatype_factory::get_fresh_value(sort * s) {
|
||||||
expr * val = get_some_value(s);
|
expr * val = get_some_value(s);
|
||||||
if (m_util.is_recursive(s))
|
if (m_util.is_recursive(s))
|
||||||
m_last_fresh_value.insert(s, val);
|
m_last_fresh_value.insert(s, val);
|
||||||
TRACE("datatype_factory", tout << "0. result: " << mk_pp(val, m_manager) << "\n";);
|
TRACE("datatype", tout << "0. result: " << mk_pp(val, m_manager) << "\n";);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
// Approach 1)
|
// Approach 1)
|
||||||
|
@ -171,13 +171,13 @@ expr * datatype_factory::get_fresh_value(sort * s) {
|
||||||
}
|
}
|
||||||
expr_ref new_value(m_manager);
|
expr_ref new_value(m_manager);
|
||||||
new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr());
|
new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr());
|
||||||
CTRACE("datatype_factory", found_fresh_arg && set->contains(new_value), tout << mk_pp(new_value, m_manager) << "\n";);
|
CTRACE("datatype", found_fresh_arg && set->contains(new_value), tout << mk_pp(new_value, m_manager) << "\n";);
|
||||||
SASSERT(!found_fresh_arg || !set->contains(new_value));
|
SASSERT(!found_fresh_arg || !set->contains(new_value));
|
||||||
if (!set->contains(new_value)) {
|
if (!set->contains(new_value)) {
|
||||||
register_value(new_value);
|
register_value(new_value);
|
||||||
if (m_util.is_recursive(s))
|
if (m_util.is_recursive(s))
|
||||||
m_last_fresh_value.insert(s, new_value);
|
m_last_fresh_value.insert(s, new_value);
|
||||||
TRACE("datatype_factory", tout << "1. result: " << mk_pp(new_value, m_manager) << "\n";);
|
TRACE("datatype", tout << "1. result: " << mk_pp(new_value, m_manager) << "\n";);
|
||||||
return new_value;
|
return new_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,16 +188,16 @@ expr * datatype_factory::get_fresh_value(sort * s) {
|
||||||
if (m_util.is_recursive(s)) {
|
if (m_util.is_recursive(s)) {
|
||||||
while(true) {
|
while(true) {
|
||||||
++num_iterations;
|
++num_iterations;
|
||||||
TRACE("datatype_factory", tout << mk_pp(get_last_fresh_value(s), m_manager) << "\n";);
|
TRACE("datatype", tout << mk_pp(get_last_fresh_value(s), m_manager) << "\n";);
|
||||||
ptr_vector<func_decl> const & constructors = *m_util.get_datatype_constructors(s);
|
ptr_vector<func_decl> const & constructors = *m_util.get_datatype_constructors(s);
|
||||||
for (func_decl * constructor : constructors) {
|
for (func_decl * constructor : constructors) {
|
||||||
expr_ref_vector args(m_manager);
|
expr_ref_vector args(m_manager);
|
||||||
bool found_sibling = false;
|
bool found_sibling = false;
|
||||||
unsigned num = constructor->get_arity();
|
unsigned num = constructor->get_arity();
|
||||||
TRACE("datatype_factory", tout << "checking constructor: " << constructor->get_name() << "\n";);
|
TRACE("datatype", tout << "checking constructor: " << constructor->get_name() << "\n";);
|
||||||
for (unsigned i = 0; i < num; i++) {
|
for (unsigned i = 0; i < num; i++) {
|
||||||
sort * s_arg = constructor->get_domain(i);
|
sort * s_arg = constructor->get_domain(i);
|
||||||
TRACE("datatype_factory", tout << mk_pp(s, m_manager) << " "
|
TRACE("datatype", tout << mk_pp(s, m_manager) << " "
|
||||||
<< mk_pp(s_arg, m_manager) << " are_siblings "
|
<< mk_pp(s_arg, m_manager) << " are_siblings "
|
||||||
<< m_util.are_siblings(s, s_arg) << " is_datatype "
|
<< m_util.are_siblings(s, s_arg) << " is_datatype "
|
||||||
<< m_util.is_datatype(s_arg) << " found_sibling "
|
<< m_util.is_datatype(s_arg) << " found_sibling "
|
||||||
|
@ -212,7 +212,7 @@ expr * datatype_factory::get_fresh_value(sort * s) {
|
||||||
maybe_new_arg = get_fresh_value(s_arg);
|
maybe_new_arg = get_fresh_value(s_arg);
|
||||||
}
|
}
|
||||||
if (!maybe_new_arg) {
|
if (!maybe_new_arg) {
|
||||||
TRACE("datatype_factory",
|
TRACE("datatype",
|
||||||
tout << "no argument found for " << mk_pp(s_arg, m_manager) << "\n";);
|
tout << "no argument found for " << mk_pp(s_arg, m_manager) << "\n";);
|
||||||
maybe_new_arg = m_model.get_some_value(s_arg);
|
maybe_new_arg = m_model.get_some_value(s_arg);
|
||||||
found_sibling = false;
|
found_sibling = false;
|
||||||
|
@ -229,11 +229,11 @@ expr * datatype_factory::get_fresh_value(sort * s) {
|
||||||
if (found_sibling) {
|
if (found_sibling) {
|
||||||
expr_ref new_value(m_manager);
|
expr_ref new_value(m_manager);
|
||||||
new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr());
|
new_value = m_manager.mk_app(constructor, args.size(), args.c_ptr());
|
||||||
TRACE("datatype_factory", tout << "potential new value: " << mk_pp(new_value, m_manager) << "\n";);
|
TRACE("datatype", tout << "potential new value: " << mk_pp(new_value, m_manager) << "\n";);
|
||||||
m_last_fresh_value.insert(s, new_value);
|
m_last_fresh_value.insert(s, new_value);
|
||||||
if (!set->contains(new_value)) {
|
if (!set->contains(new_value)) {
|
||||||
register_value(new_value);
|
register_value(new_value);
|
||||||
TRACE("datatype_factory", tout << "2. result: " << mk_pp(new_value, m_manager) << "\n";);
|
TRACE("datatype", tout << "2. result: " << mk_pp(new_value, m_manager) << "\n";);
|
||||||
return new_value;
|
return new_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue