mirror of
https://github.com/Z3Prover/z3
synced 2025-04-11 03:33:35 +00:00
add check for contravariance to fix #2256
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
082a0f4df4
commit
faf4ba8309
|
@ -446,6 +446,9 @@ namespace datatype {
|
|||
if (!u().is_well_founded(sorts.size(), sorts.c_ptr())) {
|
||||
m_manager->raise_exception("datatype is not well-founded");
|
||||
}
|
||||
if (!u().is_covariant(sorts.size(), sorts.c_ptr())) {
|
||||
m_manager->raise_exception("datatype is not co-variant");
|
||||
}
|
||||
|
||||
u().compute_datatype_size_functions(m_def_block);
|
||||
for (symbol const& s : m_def_block) {
|
||||
|
@ -851,6 +854,48 @@ namespace datatype {
|
|||
return num_well_founded == num_types;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Return true if the inductive datatype is co-variant.
|
||||
Pre-condition: The given argument constrains the parameters of an inductive datatype.
|
||||
*/
|
||||
bool util::is_covariant(unsigned num_types, sort* const* sorts) const {
|
||||
ast_mark mark;
|
||||
ptr_vector<sort> subsorts;
|
||||
|
||||
for (unsigned tid = 0; tid < num_types; tid++) {
|
||||
mark.mark(sorts[tid], true);
|
||||
}
|
||||
|
||||
for (unsigned tid = 0; tid < num_types; tid++) {
|
||||
sort* s = sorts[tid];
|
||||
def const& d = get_def(s);
|
||||
for (constructor const* c : d) {
|
||||
for (accessor const* a : *c) {
|
||||
if (!is_covariant(mark, subsorts, a->range())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool util::is_covariant(ast_mark& mark, ptr_vector<sort>& subsorts, sort* s) const {
|
||||
array_util autil(m);
|
||||
if (!autil.is_array(s)) {
|
||||
return true;
|
||||
}
|
||||
unsigned n = get_array_arity(s);
|
||||
subsorts.reset();
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
get_subsorts(get_array_domain(s, i), subsorts);
|
||||
}
|
||||
for (sort* r : subsorts) {
|
||||
if (mark.is_marked(r)) return false;
|
||||
}
|
||||
return is_covariant(mark, subsorts, get_array_range(s));
|
||||
}
|
||||
|
||||
def const& util::get_def(sort* s) const {
|
||||
return m_plugin->get_def(s);
|
||||
}
|
||||
|
|
|
@ -314,6 +314,8 @@ namespace datatype {
|
|||
void compute_datatype_size_functions(svector<symbol> const& names);
|
||||
param_size::size* get_sort_size(sort_ref_vector const& params, sort* s);
|
||||
bool is_well_founded(unsigned num_types, sort* const* sorts);
|
||||
bool is_covariant(unsigned num_types, sort* const* sorts) const;
|
||||
bool is_covariant(ast_mark& mark, ptr_vector<sort>& subsorts, sort* s) const;
|
||||
def& get_def(symbol const& s) { return m_plugin->get_def(s); }
|
||||
void get_subsorts(sort* s, ptr_vector<sort>& sorts) const;
|
||||
|
||||
|
|
Loading…
Reference in a new issue