3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-08 00:05:46 +00:00

support for smtlib2.6 datatype parsing

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-09-04 21:12:43 -07:00
parent 5492d0e135
commit 5d17e28667
29 changed files with 374 additions and 206 deletions

View file

@ -682,8 +682,6 @@ bool cmd_context::logic_has_datatype() const {
void cmd_context::init_manager_core(bool new_manager) {
SASSERT(m_manager != 0);
SASSERT(m_pmanager != 0);
m_dt_eh = alloc(dt_eh, *this);
m_pmanager->set_new_datatype_eh(m_dt_eh.get());
if (new_manager) {
decl_plugin * basic = m_manager->get_plugin(m_manager->get_basic_family_id());
register_builtin_sorts(basic);
@ -719,6 +717,8 @@ void cmd_context::init_manager_core(bool new_manager) {
}
}
}
m_dt_eh = alloc(dt_eh, *this);
m_pmanager->set_new_datatype_eh(m_dt_eh.get());
if (!has_logic()) {
// add list type only if the logic is not specified.
// it prevents clashes with builtin types.
@ -795,6 +795,7 @@ void cmd_context::insert(symbol const & s, func_decl * f) {
dictionary<func_decls>::entry * e = m_func_decls.insert_if_not_there2(s, func_decls());
func_decls & fs = e->get_data().m_value;
if (!fs.insert(m(), f)) {
UNREACHABLE();
std::string msg = "invalid declaration, ";
msg += f->get_arity() == 0 ? "constant" : "function";
msg += " '";
@ -1954,21 +1955,17 @@ cmd_context::dt_eh::~dt_eh() {
void cmd_context::dt_eh::operator()(sort * dt, pdecl* pd) {
TRACE("new_dt_eh", tout << "new datatype: "; m_owner.pm().display(tout, dt); tout << "\n";);
ptr_vector<func_decl> const & constructors = m_dt_util.get_datatype_constructors(dt);
unsigned num_constructors = constructors.size();
for (unsigned j = 0; j < num_constructors; j++) {
func_decl * c = constructors[j];
m_owner.insert(c);
for (func_decl * c : *m_dt_util.get_datatype_constructors(dt)) {
TRACE("new_dt_eh", tout << "new constructor: " << c->get_name() << "\n";);
m_owner.insert(c);
#ifndef DATATYPE_V2
func_decl * r = m_dt_util.get_constructor_recognizer(c);
m_owner.insert(r);
TRACE("new_dt_eh", tout << "new recognizer: " << r->get_name() << "\n";);
ptr_vector<func_decl> const & accessors = m_dt_util.get_constructor_accessors(c);
unsigned num_accessors = accessors.size();
for (unsigned k = 0; k < num_accessors; k++) {
func_decl * a = accessors[k];
m_owner.insert(a);
#endif
for (func_decl * a : *m_dt_util.get_constructor_accessors(c)) {
TRACE("new_dt_eh", tout << "new accessor: " << a->get_name() << "\n";);
m_owner.insert(a);
}
}
if (m_owner.m_scopes.size() > 0) {

View file

@ -170,9 +170,10 @@ public:
virtual char const * hcons_kind() const { return "psort_var"; }
virtual unsigned hcons_hash() const { return hash_u_u(m_num_params, m_idx); }
virtual bool hcons_eq(psort const * other) const {
if (other->hcons_kind() != hcons_kind())
return false;
return get_num_params() == other->get_num_params() && m_idx == static_cast<psort_var const *>(other)->m_idx;
return
other->hcons_kind() == hcons_kind() &&
get_num_params() == other->get_num_params() &&
m_idx == static_cast<psort_var const *>(other)->m_idx;
}
virtual void display(std::ostream & out) const {
out << "s_" << m_idx;
@ -344,6 +345,53 @@ void psort_user_decl::display(std::ostream & out) const {
out << ")";
}
// -------------------
// psort_dt_decl
psort_dt_decl::psort_dt_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n) :
psort_decl(id, num_params, m, n) {
m_psort_kind = PSORT_DT;
}
sort * psort_dt_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) {
#ifndef DATATYPE_V2
UNREACHABLE();
return 0;
#else
SASSERT(n == m_num_params);
sort * r = find(s);
if (r)
return r;
buffer<parameter> ps;
ps.push_back(parameter(m_name));
for (unsigned i = 0; i < n; i++)
ps.push_back(parameter(s[i]));
datatype_util util(m.m());
r = m.m().mk_sort(util.get_family_id(), DATATYPE_SORT, ps.size(), ps.c_ptr());
cache(m, s, r);
m.save_info(r, this, n, s);
if (m_num_params > 0 && util.is_declared(r)) {
bool has_typevar = false;
// crude check ..
for (unsigned i = 0; !has_typevar && i < n; ++i) {
has_typevar = s[i]->get_name().is_numerical();
}
if (!has_typevar) {
m.notify_new_dt(r, this);
}
}
return r;
#endif
}
void psort_dt_decl::display(std::ostream & out) const {
out << "(datatype-sort " << m_name << ")";
}
// -------------------
// psort_builtin_decl
psort_builtin_decl::psort_builtin_decl(unsigned id, pdecl_manager & m, symbol const & n, family_id fid, decl_kind k):
psort_decl(id, PSORT_DECL_VAR_PARAMS, m, n),
m_fid(fid),
@ -435,8 +483,8 @@ bool paccessor_decl::fix_missing_refs(dictionary<int> const & symbol2idx, symbol
accessor_decl * paccessor_decl::instantiate_decl(pdecl_manager & m, sort * const * s) {
switch (m_type.kind()) {
case PTR_REC_REF: return mk_accessor_decl(m_name, type_ref(m_type.get_idx()));
case PTR_PSORT: return mk_accessor_decl(m_name, type_ref(m_type.get_psort()->instantiate(m, s)));
case PTR_REC_REF: return mk_accessor_decl(m.m(), m_name, type_ref(m_type.get_idx()));
case PTR_PSORT: return mk_accessor_decl(m.m(), m_name, type_ref(m_type.get_psort()->instantiate(m, s)));
default:
// missing refs must have been eliminated.
UNREACHABLE();
@ -546,7 +594,7 @@ datatype_decl * pdatatype_decl::instantiate_decl(pdecl_manager & m, sort * const
cs.push_back(c->instantiate_decl(m, s));
}
datatype_util util(m.m());
return mk_datatype_decl(util, m_name, cs.size(), cs.c_ptr());
return mk_datatype_decl(util, m_name, m_num_params, s, cs.size(), cs.c_ptr());
}
struct datatype_decl_buffer {
@ -554,6 +602,12 @@ struct datatype_decl_buffer {
~datatype_decl_buffer() { del_datatype_decls(m_buffer.size(), m_buffer.c_ptr()); }
};
#ifdef DATATYPE_V2
sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) {
UNREACHABLE();
return 0;
}
#else
sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) {
SASSERT(m_num_params == n);
sort * r = find(s);
@ -583,6 +637,7 @@ sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const *
}
return 0;
}
#endif
void pdatatype_decl::display(std::ostream & out) const {
out << "(declare-datatype " << m_name;
@ -603,6 +658,27 @@ void pdatatype_decl::display(std::ostream & out) const {
out << ")";
}
#ifdef DATATYPE_V2
bool pdatatype_decl::commit(pdecl_manager& m) {
sort_ref_vector ps(m.m());
for (unsigned i = 0; i < m_num_params; ++i) {
ps.push_back(m.m().mk_uninterpreted_sort(symbol(i), 0, 0));
}
datatype_decl_buffer dts;
dts.m_buffer.push_back(instantiate_decl(m, ps.c_ptr()));
datatype_decl * d_ptr = dts.m_buffer[0];
sort_ref_vector sorts(m.m());
bool is_ok = m.get_dt_plugin()->mk_datatypes(1, &d_ptr, m_num_params, ps.c_ptr(), sorts);
if (is_ok) {
if (m_num_params == 0) {
m.notify_new_dt(sorts.get(0), this);
}
}
return is_ok;
}
#endif
pdatatypes_decl::pdatatypes_decl(unsigned id, unsigned num_params, pdecl_manager & m,
unsigned num_datatypes, pdatatype_decl * const * dts):
pdecl(id, num_params),
@ -631,6 +707,12 @@ bool pdatatypes_decl::fix_missing_refs(symbol & missing) {
return true;
}
#ifdef DATATYPE_V2
bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) {
UNREACHABLE();
return false;
}
#else
bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) {
datatype_decl_buffer dts;
for (auto d : m_datatypes) {
@ -649,6 +731,31 @@ bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) {
}
return true;
}
#endif
#ifdef DATATYPE_V2
bool pdatatypes_decl::commit(pdecl_manager& m) {
datatype_decl_buffer dts;
for (pdatatype_decl* d : m_datatypes) {
sort_ref_vector ps(m.m());
for (unsigned i = 0; i < d->get_num_params(); ++i) {
ps.push_back(m.m().mk_uninterpreted_sort(symbol(i), 0, 0));
}
dts.m_buffer.push_back(d->instantiate_decl(m, ps.c_ptr()));
}
sort_ref_vector sorts(m.m());
bool is_ok = m.get_dt_plugin()->mk_datatypes(m_datatypes.size(), dts.m_buffer.c_ptr(), 0, nullptr, sorts);
if (is_ok) {
for (unsigned i = 0; i < m_datatypes.size(); ++i) {
pdatatype_decl* d = m_datatypes[i];
if (d->get_num_params() == 0) {
m.notify_new_dt(sorts.get(i), this);
}
}
}
return is_ok;
}
#endif
struct pdecl_manager::sort_info {
psort_decl * m_decl;
@ -790,9 +897,8 @@ psort * pdecl_manager::register_psort(psort * n) {
psort * r = m_table.insert_if_not_there(n);
if (r != n) {
del_decl_core(n);
return r;
}
return n;
return r;
}
psort * pdecl_manager::mk_psort_var(unsigned num_params, unsigned vidx) {
@ -837,6 +943,11 @@ psort_decl * pdecl_manager::mk_psort_user_decl(unsigned num_params, symbol const
return new (a().allocate(sizeof(psort_user_decl))) psort_user_decl(m_id_gen.mk(), num_params, *this, n, def);
}
psort_decl * pdecl_manager::mk_psort_dt_decl(unsigned num_params, symbol const & n) {
// std::cout << "insert dt-psort: " << n << " " << num_params << "\n";
return new (a().allocate(sizeof(psort_dt_decl))) psort_dt_decl(m_id_gen.mk(), num_params, *this, n);
}
psort_decl * pdecl_manager::mk_psort_builtin_decl(symbol const & n, family_id fid, decl_kind k) {
return new (a().allocate(sizeof(psort_builtin_decl))) psort_builtin_decl(m_id_gen.mk(), *this, n, fid, k);

View file

@ -87,7 +87,7 @@ typedef ptr_hashtable<psort, psort_hash_proc, psort_eq_proc> psort_table;
#define PSORT_DECL_VAR_PARAMS UINT_MAX
typedef enum { PSORT_BASE = 0, PSORT_USER, PSORT_BUILTIN } psort_decl_kind;
typedef enum { PSORT_BASE = 0, PSORT_USER, PSORT_BUILTIN, PSORT_DT } psort_decl_kind;
class psort_decl : public pdecl {
protected:
@ -111,6 +111,7 @@ public:
virtual void reset_cache(pdecl_manager& m);
bool is_user_decl() const { return m_psort_kind == PSORT_USER; }
bool is_builtin_decl() const { return m_psort_kind == PSORT_BUILTIN; }
bool is_dt_decl() const { return m_psort_kind == PSORT_DT; }
};
class psort_user_decl : public psort_decl {
@ -125,7 +126,7 @@ public:
virtual sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s);
virtual void display(std::ostream & out) const;
};
class psort_builtin_decl : public psort_decl {
protected:
friend class pdecl_manager;
@ -140,10 +141,17 @@ public:
virtual void display(std::ostream & out) const;
};
//class datatype_decl_plugin;
//class datatype_decl;
//class constructor_decl;
//class accessor_decl;
class psort_dt_decl : public psort_decl {
protected:
friend class pdecl_manager;
psort_dt_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n);
virtual size_t obj_size() const { return sizeof(psort_dt_decl); }
virtual ~psort_dt_decl() {}
public:
virtual sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s);
virtual void display(std::ostream & out) const;
};
class pdatatypes_decl;
class pdatatype_decl;
@ -233,6 +241,9 @@ public:
virtual void display(std::ostream & out) const;
bool has_missing_refs(symbol & missing) const;
bool has_duplicate_accessors(symbol & repeated) const;
#ifdef DATATYPE_V2
bool commit(pdecl_manager& m);
#endif
};
/**
@ -250,6 +261,10 @@ class pdatatypes_decl : public pdecl {
virtual ~pdatatypes_decl() {}
public:
pdatatype_decl const * const * children() const { return m_datatypes.c_ptr(); }
#ifdef DATATYPE_V2
// commit declaration
bool commit(pdecl_manager& m);
#endif
};
class new_datatype_eh {
@ -292,7 +307,7 @@ public:
psort * mk_psort_var(unsigned num_params, unsigned vidx);
psort * mk_psort_app(unsigned num_params, psort_decl * d, unsigned num_args, psort * const * args);
psort * mk_psort_app(psort_decl * d);
// psort_decl * mk_psort_dt_decl(unsigned num_params, symbol const & n);
psort_decl * mk_psort_dt_decl(unsigned num_params, symbol const & n);
psort_decl * mk_psort_user_decl(unsigned num_params, symbol const & n, psort * def);
psort_decl * mk_psort_builtin_decl(symbol const & n, family_id fid, decl_kind k);
paccessor_decl * mk_paccessor_decl(unsigned num_params, symbol const & s, ptype const & p);