mirror of
https://github.com/Z3Prover/z3
synced 2025-04-13 12:28:44 +00:00
working on parametric datatype redo
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
fff54d5d08
commit
7fbb938474
|
@ -15,14 +15,13 @@ Author:
|
|||
|
||||
Revision History:
|
||||
|
||||
// compute sort sizes and insert them.
|
||||
// have a notion of pre-sort or just attach sort size after declaration.
|
||||
|
||||
--*/
|
||||
#include "ast/datatype_decl_plugin2.h"
|
||||
#include "util/warning.h"
|
||||
#include "ast/datatype_decl_plugin2.h"
|
||||
#include "ast/array_decl_plugin.h"
|
||||
#include "ast/ast_smt2_pp.h"
|
||||
|
||||
|
||||
namespace datatype {
|
||||
|
||||
func_decl_ref accessor::instantiate(sort_ref_vector const& ps) const {
|
||||
|
@ -78,6 +77,32 @@ namespace datatype {
|
|||
BLACK
|
||||
};
|
||||
|
||||
namespace param_size {
|
||||
size* size::mk_offset(sort_size const& s) { return alloc(offset, s); }
|
||||
size* size::mk_param(sort_ref& p) { return alloc(sparam, p); }
|
||||
size* size::mk_plus(size* a1, size* a2) { return alloc(plus, a1, a2); }
|
||||
size* size::mk_times(size* a1, size* a2) { return alloc(times, a1, a2); }
|
||||
size* size::mk_times(ptr_vector<size>& szs) {
|
||||
if (szs.empty()) return mk_offset(sort_size(1));
|
||||
if (szs.size() == 1) return szs[0];
|
||||
size* r = szs[0];
|
||||
for (unsigned i = 1; i < szs.size(); ++i) {
|
||||
r = mk_times(r, szs[i]);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
size* size::mk_plus(ptr_vector<size>& szs) {
|
||||
if (szs.empty()) return mk_offset(sort_size(0));
|
||||
if (szs.size() == 1) return szs[0];
|
||||
size* r = szs[0];
|
||||
for (unsigned i = 1; i < szs.size(); ++i) {
|
||||
r = mk_plus(r, szs[i]);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
size* size::mk_power(size* a1, size* a2) { return alloc(power, a1, a2); }
|
||||
}
|
||||
|
||||
namespace decl {
|
||||
|
||||
plugin::~plugin() {
|
||||
|
@ -125,9 +150,16 @@ namespace datatype {
|
|||
|
||||
sort* s = m_manager->mk_sort(name.get_symbol(),
|
||||
sort_info(m_family_id, k, num_parameters, parameters, true));
|
||||
// compute datatype size
|
||||
sort_size ts = u().get_datatype_size(s);
|
||||
s->set_num_elements(ts);
|
||||
def* d = 0;
|
||||
if (m_defs.find(s->get_name(), d) && d->sort_size()) {
|
||||
obj_map<sort, sort_size> S;
|
||||
for (unsigned i = 1; i < num_parameters; ++i) {
|
||||
sort* r = to_sort(parameters[i].get_ast());
|
||||
S.insert(d->params()[i], r->get_num_elements());
|
||||
}
|
||||
sort_size ts = d->sort_size()->fold(S);
|
||||
s->set_num_elements(ts);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
catch (invalid_datatype) {
|
||||
|
@ -256,6 +288,7 @@ namespace datatype {
|
|||
if (!u().is_well_founded(sorts.size(), sorts.c_ptr())) {
|
||||
m_manager->raise_exception("datatype is not well-founded");
|
||||
}
|
||||
u().compute_datatype_size_functions(m_def_block);
|
||||
}
|
||||
|
||||
void plugin::del(symbol const& s) {
|
||||
|
@ -418,84 +451,111 @@ namespace datatype {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned util::get_datatype_num_parameter_sorts(sort * ty) {
|
||||
SASSERT(ty->get_num_parameters() >= 1);
|
||||
return ty->get_num_parameters() - 1;
|
||||
}
|
||||
|
||||
sort* util::get_datatype_parameter_sort(sort * ty, unsigned idx) {
|
||||
SASSERT(idx < get_datatype_num_parameter_sorts(ty));
|
||||
return to_sort(ty->get_parameter(idx+1).get_ast());
|
||||
}
|
||||
|
||||
param_size::size* util::get_sort_size(sort_ref_vector const& params, sort* s) {
|
||||
if (params.empty()) {
|
||||
return param_size::size::mk_offset(s->get_num_elements());
|
||||
}
|
||||
if (is_datatype(s)) {
|
||||
param_size::size* sz;
|
||||
obj_map<sort, param_size::size*> S;
|
||||
unsigned n = get_datatype_num_parameter_sorts(s);
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
sort* ps = get_datatype_parameter_sort(s, i);
|
||||
sz = get_sort_size(params, ps);
|
||||
sz->inc_ref();
|
||||
S.insert(ps, sz);
|
||||
}
|
||||
def & d = get_def(s->get_name());
|
||||
sz = d.sort_size()->subst(S);
|
||||
for (auto & kv : S) {
|
||||
kv.m_value->dec_ref();
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
array_util autil(m);
|
||||
if (autil.is_array(s)) {
|
||||
unsigned n = get_array_arity(s);
|
||||
ptr_vector<param_size::size> szs;
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
szs.push_back(get_sort_size(params, get_array_domain(s, i)));
|
||||
}
|
||||
param_size::size* sz1 = param_size::size::mk_times(szs);
|
||||
param_size::size* sz2 = get_sort_size(params, get_array_range(s));
|
||||
return param_size::size::mk_power(sz2, sz1);
|
||||
}
|
||||
for (sort* p : params) {
|
||||
if (s == p) return param_size::size::mk_param(sort_ref(s, m));
|
||||
}
|
||||
return param_size::size::mk_offset(s->get_num_elements());
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Return the size of the inductive datatype.
|
||||
Pre-condition: The given argument constains the parameters of an inductive datatype.
|
||||
*/
|
||||
sort_size util::get_datatype_size(sort* s0) {
|
||||
obj_map<sort, status> already_found;
|
||||
obj_map<sort, sort_size> szs;
|
||||
ptr_vector<sort> todo;
|
||||
todo.push_back(s0);
|
||||
void util::compute_datatype_size_functions(svector<symbol> const& names) {
|
||||
map<symbol, status, symbol_hash_proc, symbol_eq_proc> already_found;
|
||||
map<symbol, param_size::size*, symbol_hash_proc, symbol_eq_proc> szs;
|
||||
|
||||
svector<symbol> todo(names);
|
||||
status st;
|
||||
while (!todo.empty()) {
|
||||
sort* s = todo.back();
|
||||
symbol s = todo.back();
|
||||
if (already_found.find(s, st) && st == BLACK) {
|
||||
todo.pop_back();
|
||||
continue;
|
||||
}
|
||||
already_found.insert(s, GRAY);
|
||||
bool is_very_big = false;
|
||||
bool can_process = true;
|
||||
def const& d = get_def(s);
|
||||
bool is_infinite = false;
|
||||
bool can_process = true;
|
||||
def& d = get_def(s);
|
||||
for (constructor const& c : d) {
|
||||
for (accessor const& a : c) {
|
||||
func_decl_ref ac = a.instantiate(s);
|
||||
sort* r = ac->get_range();
|
||||
sort* r = a.range();
|
||||
if (is_datatype(r)) {
|
||||
if (already_found.find(r, st)) {
|
||||
symbol s2 = r->get_name();
|
||||
if (already_found.find(s2, st)) {
|
||||
// type is infinite
|
||||
if (st == GRAY) return sort_size();
|
||||
if (st == GRAY) {
|
||||
is_infinite = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
todo.push_back(r);
|
||||
else if (names.contains(s2)) {
|
||||
todo.push_back(s2);
|
||||
can_process = false;
|
||||
}
|
||||
}
|
||||
else if (r->is_infinite()) {
|
||||
// type is infinite
|
||||
return sort_size();
|
||||
}
|
||||
else if (r->is_very_big()) {
|
||||
is_very_big = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!can_process) {
|
||||
continue;
|
||||
}
|
||||
todo.pop_back();
|
||||
already_found.insert(s, BLACK);
|
||||
if (is_infinite) {
|
||||
d.set_sort_size(param_size::size::mk_offset(sort_size::mk_infinite()));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (can_process) {
|
||||
todo.pop_back();
|
||||
already_found.insert(s, BLACK);
|
||||
if (is_very_big) {
|
||||
szs.insert(s, sort_size::mk_very_big());
|
||||
}
|
||||
else {
|
||||
// the type is not infinite nor the number of elements is infinite...
|
||||
// computing the number of elements
|
||||
rational num;
|
||||
def const& d = get_def(s);
|
||||
for (constructor const& c : d) {
|
||||
rational c_num(1);
|
||||
for (accessor const& a : c) {
|
||||
func_decl_ref ac = a.instantiate(s);
|
||||
sort* r = ac->get_range();
|
||||
if (szs.contains(r)) {
|
||||
c_num *= rational(szs[r].size(), rational::ui64());
|
||||
}
|
||||
else {
|
||||
SASSERT(!r->is_infinite() && !r->is_very_big());
|
||||
c_num *= rational(r->get_num_elements().size(), rational::ui64());
|
||||
}
|
||||
}
|
||||
num += c_num;
|
||||
}
|
||||
szs.insert(s, sort_size(num));
|
||||
ptr_vector<param_size::size> s_add;
|
||||
for (constructor const& c : d) {
|
||||
ptr_vector<param_size::size> s_mul;
|
||||
for (accessor const& a : c) {
|
||||
s_mul.push_back(get_sort_size(d.params(), a.range()));
|
||||
}
|
||||
s_add.push_back(param_size::size::mk_times(s_mul));
|
||||
}
|
||||
d.set_sort_size(param_size::size::mk_plus(s_add));
|
||||
}
|
||||
return szs[s0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Return true if the inductive datatype is well-founded.
|
||||
|
|
|
@ -85,11 +85,100 @@ namespace datatype {
|
|||
util& u() const;
|
||||
};
|
||||
|
||||
namespace param_size {
|
||||
class size {
|
||||
unsigned m_ref;
|
||||
public:
|
||||
size(): m_ref(0) {}
|
||||
virtual ~size() {}
|
||||
void inc_ref() { ++m_ref; }
|
||||
void dec_ref() { --m_ref; if (m_ref == 0) dealloc(this); }
|
||||
static size* mk_offset(sort_size const& s);
|
||||
static size* mk_param(sort_ref& p);
|
||||
static size* mk_plus(size* a1, size* a2);
|
||||
static size* mk_times(size* a1, size* a2);
|
||||
static size* mk_plus(ptr_vector<size>& szs);
|
||||
static size* mk_times(ptr_vector<size>& szs);
|
||||
static size* mk_power(size* a1, size* a2);
|
||||
|
||||
virtual size* subst(obj_map<sort, size*>& S) = 0;
|
||||
virtual sort_size fold(obj_map<sort, sort_size> const& S) = 0;
|
||||
|
||||
};
|
||||
struct offset : public size {
|
||||
sort_size m_offset;
|
||||
offset(sort_size const& s): m_offset(s) {}
|
||||
virtual ~offset() {}
|
||||
virtual size* subst(obj_map<sort,size*>& S) { return this; }
|
||||
virtual sort_size fold(obj_map<sort, sort_size> const& S) { return m_offset; }
|
||||
};
|
||||
struct plus : public size {
|
||||
size* m_arg1, *m_arg2;
|
||||
plus(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref();}
|
||||
virtual ~plus() { m_arg1->dec_ref(); m_arg2->dec_ref(); }
|
||||
virtual size* subst(obj_map<sort,size*>& S) { return mk_plus(m_arg1->subst(S), m_arg2->subst(S)); }
|
||||
virtual sort_size fold(obj_map<sort, sort_size> const& S) {
|
||||
sort_size s1 = m_arg1->fold(S);
|
||||
sort_size s2 = m_arg2->fold(S);
|
||||
if (s1.is_infinite()) return s1;
|
||||
if (s2.is_infinite()) return s2;
|
||||
if (s1.is_very_big()) return s1;
|
||||
if (s2.is_very_big()) return s2;
|
||||
rational r = rational(s1.size(), rational::ui64()) + rational(s2.size(), rational::ui64());
|
||||
return sort_size(r);
|
||||
}
|
||||
};
|
||||
struct times : public size {
|
||||
size* m_arg1, *m_arg2;
|
||||
times(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); }
|
||||
virtual ~times() { m_arg1->dec_ref(); m_arg2->dec_ref(); }
|
||||
virtual size* subst(obj_map<sort,size*>& S) { return mk_times(m_arg1->subst(S), m_arg2->subst(S)); }
|
||||
virtual sort_size fold(obj_map<sort, sort_size> const& S) {
|
||||
sort_size s1 = m_arg1->fold(S);
|
||||
sort_size s2 = m_arg2->fold(S);
|
||||
if (s1.is_infinite()) return s1;
|
||||
if (s2.is_infinite()) return s2;
|
||||
if (s1.is_very_big()) return s1;
|
||||
if (s2.is_very_big()) return s2;
|
||||
rational r = rational(s1.size(), rational::ui64()) * rational(s2.size(), rational::ui64());
|
||||
return sort_size(r);
|
||||
}
|
||||
};
|
||||
struct power : public size {
|
||||
size* m_arg1, *m_arg2;
|
||||
power(size* a1, size* a2): m_arg1(a1), m_arg2(a2) { a1->inc_ref(); a2->inc_ref(); }
|
||||
virtual ~power() { m_arg1->dec_ref(); m_arg2->dec_ref(); }
|
||||
virtual size* subst(obj_map<sort,size*>& S) { return mk_power(m_arg1->subst(S), m_arg2->subst(S)); }
|
||||
virtual sort_size fold(obj_map<sort, sort_size> const& S) {
|
||||
sort_size s1 = m_arg1->fold(S);
|
||||
sort_size s2 = m_arg2->fold(S);
|
||||
// s1^s2
|
||||
if (s1.is_infinite()) return s1;
|
||||
if (s2.is_infinite()) return s2;
|
||||
if (s1.is_very_big()) return s1;
|
||||
if (s2.is_very_big()) return s2;
|
||||
if (s1.size() == 1) return s1;
|
||||
if (s2.size() == 1) return s1;
|
||||
if (s1.size() > (2 << 20) || s2.size() > 10) return sort_size::mk_very_big();
|
||||
rational r = ::power(rational(s1.size(), rational::ui64()), static_cast<unsigned>(s2.size()));
|
||||
return sort_size(r);
|
||||
}
|
||||
};
|
||||
struct sparam : public size {
|
||||
sort_ref m_param;
|
||||
sparam(sort_ref& p): m_param(p) {}
|
||||
virtual ~sparam() {}
|
||||
virtual size* subst(obj_map<sort,size*>& S) { return S[m_param]; }
|
||||
virtual sort_size fold(obj_map<sort, sort_size> const& S) { return S[m_param]; }
|
||||
};
|
||||
};
|
||||
|
||||
class def {
|
||||
ast_manager& m;
|
||||
util& m_util;
|
||||
symbol m_name;
|
||||
unsigned m_class_id;
|
||||
param_size::size* m_sort_size;
|
||||
sort_ref_vector m_params;
|
||||
mutable sort_ref m_sort;
|
||||
vector<constructor> m_constructors;
|
||||
|
@ -99,9 +188,13 @@ namespace datatype {
|
|||
m_util(u),
|
||||
m_name(n),
|
||||
m_class_id(class_id),
|
||||
m_sort_size(0),
|
||||
m_params(m, num_params, params),
|
||||
m_sort(m)
|
||||
{}
|
||||
~def() {
|
||||
if (m_sort_size) m_sort_size->dec_ref();
|
||||
}
|
||||
void add(constructor& c) {
|
||||
m_constructors.push_back(c);
|
||||
c.attach(this);
|
||||
|
@ -114,6 +207,8 @@ namespace datatype {
|
|||
vector<constructor>::const_iterator end() const { return m_constructors.end(); }
|
||||
sort_ref_vector const& params() const { return m_params; }
|
||||
util& u() const { return m_util; }
|
||||
param_size::size* sort_size() { return m_sort_size; }
|
||||
void set_sort_size(param_size::size* p) { m_sort_size = p; p->inc_ref(); }
|
||||
};
|
||||
|
||||
namespace decl {
|
||||
|
@ -155,7 +250,8 @@ namespace datatype {
|
|||
|
||||
void del(symbol const& d);
|
||||
|
||||
def const& get_def(sort* s) const { def* d = 0; VERIFY(m_defs.find(datatype_name(s), d)); return *d; }
|
||||
def const& get_def(sort* s) const { return *(m_defs[datatype_name(s)]); }
|
||||
def& get_def(symbol const& s) { return *(m_defs[s]); }
|
||||
|
||||
private:
|
||||
bool is_value_visit(expr * arg, ptr_buffer<app> & todo) const;
|
||||
|
@ -213,8 +309,11 @@ namespace datatype {
|
|||
|
||||
bool is_recursive_core(sort * s) const;
|
||||
sort_size get_datatype_size(sort* s0);
|
||||
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);
|
||||
def const& get_def(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;
|
||||
|
||||
public:
|
||||
|
|
|
@ -39,15 +39,13 @@ public:
|
|||
}
|
||||
else {
|
||||
SASSERT(m_const == 0);
|
||||
obj_map<sort, void *>::iterator it = m_map.begin();
|
||||
obj_map<sort, void *>::iterator end = m_map.end();
|
||||
for (; it != end; ++it) {
|
||||
m.m().dec_ref((*it).m_key);
|
||||
for (auto kv : m_map) {
|
||||
m.m().dec_ref(kv.m_key);
|
||||
if (m_num_params == 1) {
|
||||
m.m().dec_ref(static_cast<sort*>((*it).m_value));
|
||||
m.m().dec_ref(static_cast<sort*>(kv.m_value));
|
||||
}
|
||||
else {
|
||||
psort_inst_cache * child = static_cast<psort_inst_cache*>((*it).m_value);
|
||||
psort_inst_cache * child = static_cast<psort_inst_cache*>(kv.m_value);
|
||||
child->finalize(m);
|
||||
child->~psort_inst_cache();
|
||||
m.a().deallocate(sizeof(psort_inst_cache), child);
|
||||
|
@ -485,20 +483,16 @@ void pconstructor_decl::finalize(pdecl_manager & m) {
|
|||
}
|
||||
|
||||
bool pconstructor_decl::has_missing_refs(symbol & missing) const {
|
||||
ptr_vector<paccessor_decl>::const_iterator it = m_accessors.begin();
|
||||
ptr_vector<paccessor_decl>::const_iterator end = m_accessors.end();
|
||||
for (; it != end; ++it) {
|
||||
if ((*it)->has_missing_refs(missing))
|
||||
for (paccessor_decl* a : m_accessors) {
|
||||
if (a->has_missing_refs(missing))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pconstructor_decl::fix_missing_refs(dictionary<int> const & symbol2idx, symbol & missing) {
|
||||
ptr_vector<paccessor_decl>::iterator it = m_accessors.begin();
|
||||
ptr_vector<paccessor_decl>::iterator end = m_accessors.end();
|
||||
for (; it != end; ++it) {
|
||||
if (!(*it)->fix_missing_refs(symbol2idx, missing))
|
||||
for (paccessor_decl* a : m_accessors) {
|
||||
if (!a->fix_missing_refs(symbol2idx, missing))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -506,20 +500,16 @@ bool pconstructor_decl::fix_missing_refs(dictionary<int> const & symbol2idx, sym
|
|||
|
||||
constructor_decl * pconstructor_decl::instantiate_decl(pdecl_manager & m, sort * const * s) {
|
||||
ptr_buffer<accessor_decl> as;
|
||||
ptr_vector<paccessor_decl>::iterator it = m_accessors.begin();
|
||||
ptr_vector<paccessor_decl>::iterator end = m_accessors.end();
|
||||
for (; it != end; ++it)
|
||||
as.push_back((*it)->instantiate_decl(m, s));
|
||||
for (paccessor_decl* a : m_accessors)
|
||||
as.push_back(a->instantiate_decl(m, s));
|
||||
return mk_constructor_decl(m_name, m_recogniser_name, as.size(), as.c_ptr());
|
||||
}
|
||||
|
||||
void pconstructor_decl::display(std::ostream & out, pdatatype_decl const * const * dts) const {
|
||||
out << "(" << m_name;
|
||||
ptr_vector<paccessor_decl>::const_iterator it = m_accessors.begin();
|
||||
ptr_vector<paccessor_decl>::const_iterator end = m_accessors.end();
|
||||
for (; it != end; ++it) {
|
||||
for (paccessor_decl* a : m_accessors) {
|
||||
out << " ";
|
||||
(*it)->display(out, dts);
|
||||
a->display(out, dts);
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
|
@ -538,23 +528,17 @@ void pdatatype_decl::finalize(pdecl_manager & m) {
|
|||
}
|
||||
|
||||
bool pdatatype_decl::has_missing_refs(symbol & missing) const {
|
||||
ptr_vector<pconstructor_decl>::const_iterator it = m_constructors.begin();
|
||||
ptr_vector<pconstructor_decl>::const_iterator end = m_constructors.end();
|
||||
for (; it != end; ++it) {
|
||||
if ((*it)->has_missing_refs(missing))
|
||||
for (auto c : m_constructors)
|
||||
if (c->has_missing_refs(missing))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pdatatype_decl::has_duplicate_accessors(symbol & duplicated) const {
|
||||
hashtable<symbol, symbol_hash_proc, symbol_eq_proc> names;
|
||||
ptr_vector<pconstructor_decl>::const_iterator it = m_constructors.begin();
|
||||
ptr_vector<pconstructor_decl>::const_iterator end = m_constructors.end();
|
||||
for (; it != end; ++it) {
|
||||
ptr_vector<paccessor_decl> const& acc = (*it)->m_accessors;
|
||||
for (unsigned i = 0; i < acc.size(); ++i) {
|
||||
symbol const& name = acc[i]->get_name();
|
||||
for (auto c : m_constructors) {
|
||||
for (auto a : c->m_accessors) {
|
||||
symbol const& name = a->get_name();
|
||||
if (names.contains(name)) {
|
||||
duplicated = name;
|
||||
return true;
|
||||
|
@ -567,10 +551,8 @@ bool pdatatype_decl::has_duplicate_accessors(symbol & duplicated) const {
|
|||
|
||||
|
||||
bool pdatatype_decl::fix_missing_refs(dictionary<int> const & symbol2idx, symbol & missing) {
|
||||
ptr_vector<pconstructor_decl>::iterator it = m_constructors.begin();
|
||||
ptr_vector<pconstructor_decl>::iterator end = m_constructors.end();
|
||||
for (; it != end; ++it) {
|
||||
if (!(*it)->fix_missing_refs(symbol2idx, missing))
|
||||
for (auto c : m_constructors) {
|
||||
if (!c->fix_missing_refs(symbol2idx, missing))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -578,10 +560,8 @@ bool pdatatype_decl::fix_missing_refs(dictionary<int> const & symbol2idx, symbol
|
|||
|
||||
datatype_decl * pdatatype_decl::instantiate_decl(pdecl_manager & m, sort * const * s) {
|
||||
ptr_buffer<constructor_decl> cs;
|
||||
ptr_vector<pconstructor_decl>::iterator it = m_constructors.begin();
|
||||
ptr_vector<pconstructor_decl>::iterator end = m_constructors.end();
|
||||
for (; it != end; ++it) {
|
||||
cs.push_back((*it)->instantiate_decl(m, s));
|
||||
for (auto c : m_constructors) {
|
||||
cs.push_back(c->instantiate_decl(m, s));
|
||||
}
|
||||
return mk_datatype_decl(m_name, cs.size(), cs.c_ptr());
|
||||
}
|
||||
|
@ -624,17 +604,16 @@ sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const *
|
|||
void pdatatype_decl::display(std::ostream & out) const {
|
||||
out << "(declare-datatype " << m_name;
|
||||
display_sort_args(out, m_num_params);
|
||||
ptr_vector<pconstructor_decl>::const_iterator it = m_constructors.begin();
|
||||
ptr_vector<pconstructor_decl>::const_iterator end = m_constructors.end();
|
||||
for (bool first = true; it != end; ++it) {
|
||||
bool first = true;
|
||||
for (auto c : m_constructors) {
|
||||
if (!first)
|
||||
out << " ";
|
||||
if (m_parent) {
|
||||
(*it)->display(out, m_parent->children());
|
||||
c->display(out, m_parent->children());
|
||||
}
|
||||
else {
|
||||
pdatatype_decl const * dts[1] = { this };
|
||||
(*it)->display(out, dts);
|
||||
c->display(out, dts);
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
@ -647,11 +626,9 @@ pdatatypes_decl::pdatatypes_decl(unsigned id, unsigned num_params, pdecl_manager
|
|||
m_datatypes(num_datatypes, dts) {
|
||||
m.inc_ref(num_datatypes, dts);
|
||||
|
||||
ptr_vector<pdatatype_decl>::iterator it = m_datatypes.begin();
|
||||
ptr_vector<pdatatype_decl>::iterator end = m_datatypes.end();
|
||||
for (; it != end; ++it) {
|
||||
SASSERT((*it)->m_parent == 0);
|
||||
(*it)->m_parent = this;
|
||||
for (auto d : m_datatypes) {
|
||||
SASSERT(d->m_parent == 0);
|
||||
d->m_parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,36 +639,30 @@ void pdatatypes_decl::finalize(pdecl_manager & m) {
|
|||
bool pdatatypes_decl::fix_missing_refs(symbol & missing) {
|
||||
TRACE("fix_missing_refs", tout << "pdatatypes_decl::fix_missing_refs\n";);
|
||||
dictionary<int> symbol2idx;
|
||||
ptr_vector<pdatatype_decl>::iterator it = m_datatypes.begin();
|
||||
ptr_vector<pdatatype_decl>::iterator end = m_datatypes.end();
|
||||
for (unsigned idx = 0; it != end; ++it, ++idx)
|
||||
symbol2idx.insert((*it)->get_name(), idx);
|
||||
|
||||
it = m_datatypes.begin();
|
||||
for (unsigned idx = 0; it != end; ++it, ++idx) {
|
||||
if (!(*it)->fix_missing_refs(symbol2idx, missing))
|
||||
int idx = 0;
|
||||
for (pdatatype_decl* d : m_datatypes)
|
||||
symbol2idx.insert(d->get_name(), idx++);
|
||||
for (pdatatype_decl* d : m_datatypes)
|
||||
if (!d->fix_missing_refs(symbol2idx, missing))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) {
|
||||
datatype_decl_buffer dts;
|
||||
ptr_vector<pdatatype_decl>::iterator it = m_datatypes.begin();
|
||||
ptr_vector<pdatatype_decl>::iterator end = m_datatypes.end();
|
||||
for (; it != end; ++it) {
|
||||
dts.m_buffer.push_back((*it)->instantiate_decl(m, s));
|
||||
for (auto d : m_datatypes) {
|
||||
dts.m_buffer.push_back(d->instantiate_decl(m, s));
|
||||
}
|
||||
sort_ref_vector sorts(m.m());
|
||||
bool is_ok = m.get_dt_plugin()->mk_datatypes(dts.m_buffer.size(), dts.m_buffer.c_ptr(), m_num_params, s, sorts);
|
||||
if (!is_ok)
|
||||
return false;
|
||||
it = m_datatypes.begin();
|
||||
for (unsigned i = 0; it != end; ++it, ++i) {
|
||||
sort * new_dt = sorts.get(i);
|
||||
(*it)->cache(m, s, new_dt);
|
||||
m.save_info(new_dt, *it, m_num_params, s);
|
||||
m.notify_new_dt(new_dt, *it);
|
||||
unsigned i = 0;
|
||||
for (auto d : m_datatypes) {
|
||||
sort * new_dt = sorts.get(i++);
|
||||
d->cache(m, s, new_dt);
|
||||
m.save_info(new_dt, d, m_num_params, s);
|
||||
m.notify_new_dt(new_dt, d);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -965,11 +936,9 @@ void pdecl_manager::save_info(sort * s, psort_decl * d, unsigned num_indices, un
|
|||
}
|
||||
|
||||
void pdecl_manager::reset_sort_info() {
|
||||
obj_map<sort, sort_info *>::iterator it = m_sort2info.begin();
|
||||
obj_map<sort, sort_info *>::iterator end = m_sort2info.end();
|
||||
for (; it != end; ++it) {
|
||||
sort * s = (*it).m_key;
|
||||
sort_info * info = (*it).m_value;
|
||||
for (auto kv : m_sort2info) {
|
||||
sort * s = kv.m_key;
|
||||
sort_info * info = kv.m_value;
|
||||
m().dec_ref(s);
|
||||
unsigned sz = info->obj_size();
|
||||
info->finalize(*this);
|
||||
|
|
|
@ -134,20 +134,6 @@ public:
|
|||
virtual void display(std::ostream & out) const;
|
||||
};
|
||||
|
||||
#if 0
|
||||
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 void finalize(pdecl_manager & m);
|
||||
virtual ~psort_dt_decl() {}
|
||||
public:
|
||||
virtual sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s);
|
||||
virtual void display(std::ostream & out) const;
|
||||
};
|
||||
#endif
|
||||
|
||||
class datatype_decl_plugin;
|
||||
class datatype_decl;
|
||||
class constructor_decl;
|
||||
|
|
Loading…
Reference in a new issue