mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
fixes to #1155 and partial introduction of SMTLIB 2.6 datatype format
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
2b0106c199
commit
a0a8bc2a62
13 changed files with 452 additions and 156 deletions
|
@ -431,6 +431,14 @@ format_ns::format * smt2_pp_environment::pp_sort(sort * s) {
|
|||
fs.push_back(pp_sort(to_sort(s->get_parameter(0).get_ast())));
|
||||
return mk_seq1(m, fs.begin(), fs.end(), f2f(), get_sutil().is_seq(s)?"Seq":"Re");
|
||||
}
|
||||
if (get_dtutil().is_datatype(s)) {
|
||||
ptr_buffer<format> fs;
|
||||
unsigned sz = get_dtutil().get_datatype_num_parameter_sorts(s);
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
fs.push_back(pp_sort(get_dtutil().get_datatype_parameter_sort(s, i)));
|
||||
}
|
||||
return mk_seq1(m, fs.begin(), fs.end(), f2f(), s->get_name().str().c_str());
|
||||
}
|
||||
return format_ns::mk_string(get_manager(), s->get_name().str().c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ Revision History:
|
|||
#include"fpa_decl_plugin.h"
|
||||
#include"dl_decl_plugin.h"
|
||||
#include"seq_decl_plugin.h"
|
||||
#include"datatype_decl_plugin.h"
|
||||
#include"smt2_util.h"
|
||||
|
||||
class smt2_pp_environment {
|
||||
|
@ -50,6 +51,7 @@ public:
|
|||
virtual fpa_util & get_futil() = 0;
|
||||
virtual seq_util & get_sutil() = 0;
|
||||
virtual datalog::dl_decl_util& get_dlutil() = 0;
|
||||
virtual datatype_util& get_dtutil() = 0;
|
||||
virtual bool uses(symbol const & s) const = 0;
|
||||
virtual format_ns::format * pp_fdecl(func_decl * f, unsigned & len);
|
||||
virtual format_ns::format * pp_bv_literal(app * t, bool use_bv_lits, bool bv_neg);
|
||||
|
@ -74,9 +76,10 @@ class smt2_pp_environment_dbg : public smt2_pp_environment {
|
|||
array_util m_arutil;
|
||||
fpa_util m_futil;
|
||||
seq_util m_sutil;
|
||||
datatype_util m_dtutil;
|
||||
datalog::dl_decl_util m_dlutil;
|
||||
public:
|
||||
smt2_pp_environment_dbg(ast_manager & m):m_manager(m), m_autil(m), m_bvutil(m), m_arutil(m), m_futil(m), m_sutil(m), m_dlutil(m) {}
|
||||
smt2_pp_environment_dbg(ast_manager & m):m_manager(m), m_autil(m), m_bvutil(m), m_arutil(m), m_futil(m), m_sutil(m), m_dtutil(m), m_dlutil(m) {}
|
||||
virtual ast_manager & get_manager() const { return m_manager; }
|
||||
virtual arith_util & get_autil() { return m_autil; }
|
||||
virtual bv_util & get_bvutil() { return m_bvutil; }
|
||||
|
@ -84,6 +87,7 @@ public:
|
|||
virtual array_util & get_arutil() { return m_arutil; }
|
||||
virtual fpa_util & get_futil() { return m_futil; }
|
||||
virtual datalog::dl_decl_util& get_dlutil() { return m_dlutil; }
|
||||
virtual datatype_util& get_dtutil() { return m_dtutil; }
|
||||
virtual bool uses(symbol const & s) const { return false; }
|
||||
};
|
||||
|
||||
|
|
|
@ -366,7 +366,20 @@ class smt_printer {
|
|||
return;
|
||||
}
|
||||
else if (s->is_sort_of(m_dt_fid, DATATYPE_SORT)) {
|
||||
m_out << m_renaming.get_symbol(s->get_name());
|
||||
datatype_util util(m_manager);
|
||||
unsigned num_sorts = util.get_datatype_num_parameter_sorts(s);
|
||||
if (num_sorts > 0) {
|
||||
m_out << "(";
|
||||
}
|
||||
|
||||
m_out << m_renaming.get_symbol(s->get_name());
|
||||
if (num_sorts > 0) {
|
||||
for (unsigned i = 0; i < num_sorts; ++i) {
|
||||
m_out << " ";
|
||||
visit_sort(util.get_datatype_parameter_sort(s, i));
|
||||
}
|
||||
m_out << ")";
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -20,6 +20,7 @@ Revision History:
|
|||
#include"warning.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
|
||||
|
||||
/**
|
||||
\brief Auxiliary class used to declare inductive datatypes.
|
||||
*/
|
||||
|
@ -124,6 +125,7 @@ static parameter const & read(unsigned num_parameters, parameter const * paramet
|
|||
static int read_int(unsigned num_parameters, parameter const * parameters, unsigned idx, bool_buffer & read_pos) {
|
||||
const parameter & r = read(num_parameters, parameters, idx, read_pos);
|
||||
if (!r.is_int()) {
|
||||
TRACE("datatype", tout << "expected integer parameter at position " << idx << " got: " << r << "\n";);
|
||||
throw invalid_datatype();
|
||||
}
|
||||
return r.get_int();
|
||||
|
@ -132,11 +134,25 @@ static int read_int(unsigned num_parameters, parameter const * parameters, unsig
|
|||
static symbol read_symbol(unsigned num_parameters, parameter const * parameters, unsigned idx, bool_buffer & read_pos) {
|
||||
parameter const & r = read(num_parameters, parameters, idx, read_pos);
|
||||
if (!r.is_symbol()) {
|
||||
TRACE("datatype", tout << "expected symol parameter at position " << idx << " got: " << r << "\n";);
|
||||
throw invalid_datatype();
|
||||
}
|
||||
return r.get_symbol();
|
||||
}
|
||||
|
||||
static sort* read_sort(unsigned num_parameters, parameter const * parameters, unsigned idx, bool_buffer & read_pos) {
|
||||
parameter const & r = read(num_parameters, parameters, idx, read_pos);
|
||||
if (!r.is_ast()) {
|
||||
TRACE("datatype", tout << "expected ast parameter at position " << idx << " got: " << r << "\n";);
|
||||
throw invalid_datatype();
|
||||
}
|
||||
ast* a = r.get_ast();
|
||||
if (!is_sort(a)) {
|
||||
throw invalid_datatype();
|
||||
}
|
||||
return to_sort(a);
|
||||
}
|
||||
|
||||
enum status {
|
||||
WHITE,
|
||||
GRAY,
|
||||
|
@ -160,7 +176,7 @@ static bool is_recursive_datatype(parameter const * parameters) {
|
|||
continue;
|
||||
}
|
||||
already_found[tid] = GRAY;
|
||||
unsigned o = parameters[2 + 2*tid + 1].get_int(); // constructor offset
|
||||
unsigned o = datatype_decl_plugin::constructor_offset(parameters, tid); // constructor offset
|
||||
unsigned num_constructors = parameters[o].get_int();
|
||||
bool can_process = true;
|
||||
for (unsigned s = 1; s <= num_constructors; s++) {
|
||||
|
@ -210,7 +226,7 @@ static sort_size get_datatype_size(parameter const * parameters) {
|
|||
continue;
|
||||
}
|
||||
already_found[tid] = GRAY;
|
||||
unsigned o = parameters[2 + 2*tid + 1].get_int(); // constructor offset
|
||||
unsigned o = datatype_decl_plugin::constructor_offset(parameters, tid);
|
||||
unsigned num_constructors = parameters[o].get_int();
|
||||
bool is_very_big = false;
|
||||
bool can_process = true;
|
||||
|
@ -296,7 +312,7 @@ static bool is_well_founded(parameter const * parameters) {
|
|||
changed = false;
|
||||
for (unsigned tid = 0; tid < num_types; tid++) {
|
||||
if (!well_founded[tid]) {
|
||||
unsigned o = parameters[2 + 2*tid + 1].get_int(); // constructor offset
|
||||
unsigned o = datatype_decl_plugin::constructor_offset(parameters, tid); // constructor offset
|
||||
unsigned num_constructors = parameters[o].get_int();
|
||||
for (unsigned s = 1; s <= num_constructors; s++) {
|
||||
unsigned k_i = parameters[o + s].get_int();
|
||||
|
@ -350,9 +366,14 @@ sort * datatype_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, param
|
|||
throw invalid_datatype();
|
||||
}
|
||||
unsigned tid = read_int(num_parameters, parameters, 1, found);
|
||||
unsigned num_sort_params = read_int(num_parameters, parameters, 2, found);
|
||||
for (unsigned j = 0; j < num_sort_params; ++j) {
|
||||
read_sort(num_parameters, parameters, 3 + j, found);
|
||||
}
|
||||
unsigned c_offset = constructor_offset(parameters);
|
||||
for (unsigned j = 0; j < num_types; j++) {
|
||||
read_symbol(num_parameters, parameters, 2 + 2*j, found); // type name
|
||||
unsigned o = read_int(num_parameters, parameters, 2 + 2*j + 1, found);
|
||||
read_symbol(num_parameters, parameters, c_offset + 2*j, found); // type name
|
||||
unsigned o = read_int(num_parameters, parameters, c_offset + 2*j + 1, found);
|
||||
unsigned num_constructors = read_int(num_parameters, parameters, o, found);
|
||||
if (num_constructors == 0) {
|
||||
throw invalid_datatype();
|
||||
|
@ -368,9 +389,9 @@ sort * datatype_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, param
|
|||
parameter const & a_type = read(num_parameters, parameters, first_accessor + 2*r + 1, found); // accessort type
|
||||
if (!a_type.is_int() && !a_type.is_ast()) {
|
||||
throw invalid_datatype();
|
||||
if (a_type.is_ast() && !is_sort(a_type.get_ast())) {
|
||||
throw invalid_datatype();
|
||||
}
|
||||
}
|
||||
if (a_type.is_ast() && !is_sort(a_type.get_ast())) {
|
||||
throw invalid_datatype();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -387,7 +408,7 @@ sort * datatype_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, param
|
|||
|
||||
// compute datatype size
|
||||
sort_size ts = get_datatype_size(parameters);
|
||||
symbol const & tname = parameters[2+2*tid].get_symbol();
|
||||
symbol const & tname = parameters[c_offset + 2*tid].get_symbol();
|
||||
return m_manager->mk_sort(tname,
|
||||
sort_info(m_family_id, k, ts, num_parameters, parameters, true));
|
||||
}
|
||||
|
@ -489,7 +510,7 @@ func_decl * datatype_decl_plugin::mk_func_decl(decl_kind k, unsigned num_paramet
|
|||
}
|
||||
unsigned c_idx = parameters[1].get_int();
|
||||
unsigned tid = datatype->get_parameter(1).get_int();
|
||||
unsigned o = datatype->get_parameter(2 + 2 * tid + 1).get_int();
|
||||
unsigned o = datatype_decl_plugin::constructor_offset(datatype, tid);
|
||||
unsigned num_constructors = datatype->get_parameter(o).get_int();
|
||||
if (c_idx >= num_constructors) {
|
||||
m_manager->raise_exception("invalid parameters for datatype operator");
|
||||
|
@ -504,8 +525,6 @@ func_decl * datatype_decl_plugin::mk_func_decl(decl_kind k, unsigned num_paramet
|
|||
return 0;
|
||||
}
|
||||
else {
|
||||
|
||||
|
||||
symbol c_name = datatype->get_parameter(k_i).get_symbol();
|
||||
unsigned num_accessors = datatype->get_parameter(k_i + 2).get_int();
|
||||
if (num_accessors != arity) {
|
||||
|
@ -577,16 +596,22 @@ func_decl * datatype_decl_plugin::mk_func_decl(decl_kind k, unsigned num_paramet
|
|||
}
|
||||
}
|
||||
|
||||
bool datatype_decl_plugin::mk_datatypes(unsigned num_datatypes, datatype_decl * const * datatypes, sort_ref_vector & new_types) {
|
||||
bool datatype_decl_plugin::mk_datatypes(unsigned num_datatypes, datatype_decl * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_types) {
|
||||
buffer<parameter> p;
|
||||
p.push_back(parameter(num_datatypes));
|
||||
p.push_back(parameter(-1));
|
||||
p.push_back(parameter(num_params));
|
||||
for (unsigned i = 0; i < num_params; ++i) {
|
||||
p.push_back(parameter(sort_params[i]));
|
||||
}
|
||||
|
||||
unsigned c_offset = constructor_offset(p.c_ptr());
|
||||
for (unsigned i = 0; i < num_datatypes; i++) {
|
||||
p.push_back(parameter(datatypes[i]->get_name()));
|
||||
p.push_back(parameter(-1)); // offset is unknown at this point
|
||||
}
|
||||
for (unsigned i = 0; i < num_datatypes; i++) {
|
||||
p[3+2*i] = parameter(p.size()); // save offset to constructor table
|
||||
p[c_offset + 1 + 2*i] = parameter(p.size()); // save offset to constructor table
|
||||
ptr_vector<constructor_decl> const & constructors = datatypes[i]->get_constructors();
|
||||
unsigned num_constructors = constructors.size();
|
||||
p.push_back(parameter(num_constructors));
|
||||
|
@ -595,7 +620,7 @@ bool datatype_decl_plugin::mk_datatypes(unsigned num_datatypes, datatype_decl *
|
|||
}
|
||||
}
|
||||
for (unsigned i = 0; i < num_datatypes; i++) {
|
||||
unsigned o = p[3+2*i].get_int();
|
||||
unsigned o = constructor_offset(p.c_ptr(), i);
|
||||
ptr_vector<constructor_decl> const & constructors = datatypes[i]->get_constructors();
|
||||
unsigned num_constructors = constructors.size();
|
||||
for (unsigned j = 0; j < num_constructors; j++) {
|
||||
|
@ -655,7 +680,7 @@ bool datatype_decl_plugin::is_fully_interp(sort const * s) const {
|
|||
parameter const * parameters = s->get_parameters();
|
||||
unsigned num_types = parameters[0].get_int();
|
||||
for (unsigned tid = 0; tid < num_types; tid++) {
|
||||
unsigned o = parameters[2 + 2*tid + 1].get_int(); // constructor offset
|
||||
unsigned o = datatype_decl_plugin::constructor_offset(s, tid);
|
||||
unsigned num_constructors = parameters[o].get_int();
|
||||
for (unsigned si = 1; si <= num_constructors; si++) {
|
||||
unsigned k_i = parameters[o + si].get_int();
|
||||
|
@ -692,6 +717,28 @@ bool datatype_decl_plugin::is_value_visit(expr * arg, ptr_buffer<app> & todo) co
|
|||
}
|
||||
}
|
||||
|
||||
unsigned datatype_decl_plugin::constructor_offset(sort const* s) {
|
||||
return constructor_offset(s->get_parameters());
|
||||
}
|
||||
|
||||
unsigned datatype_decl_plugin::constructor_offset(parameter const& p) {
|
||||
return 3 + p.get_int();
|
||||
}
|
||||
|
||||
unsigned datatype_decl_plugin::constructor_offset(parameter const* ps) {
|
||||
return constructor_offset(ps[2]);
|
||||
}
|
||||
|
||||
unsigned datatype_decl_plugin::constructor_offset(sort const* s, unsigned tid) {
|
||||
unsigned c_offset = constructor_offset(s->get_parameters());
|
||||
return s->get_parameter(c_offset + 1 + 2*tid).get_int();
|
||||
}
|
||||
|
||||
unsigned datatype_decl_plugin::constructor_offset(parameter const* ps, unsigned tid) {
|
||||
unsigned c_offset = constructor_offset(ps[2]);
|
||||
return ps[c_offset + 1 + 2*tid].get_int();
|
||||
}
|
||||
|
||||
bool datatype_decl_plugin::is_value(app * e) const {
|
||||
TRACE("dt_is_value", tout << "checking\n" << mk_ismt2_pp(e, *m_manager) << "\n";);
|
||||
if (!get_util().is_constructor(e))
|
||||
|
@ -742,7 +789,7 @@ datatype_util::~datatype_util() {
|
|||
|
||||
func_decl * datatype_util::get_constructor(sort * ty, unsigned c_id) {
|
||||
unsigned tid = ty->get_parameter(1).get_int();
|
||||
unsigned o = ty->get_parameter(3 + 2*tid).get_int();
|
||||
unsigned o = datatype_decl_plugin::constructor_offset(ty, tid);
|
||||
unsigned k_i = ty->get_parameter(o + c_id + 1).get_int();
|
||||
unsigned num_accessors = ty->get_parameter(k_i + 2).get_int();
|
||||
parameter p[2] = { parameter(ty), parameter(c_id) };
|
||||
|
@ -765,7 +812,7 @@ ptr_vector<func_decl> const * datatype_util::get_datatype_constructors(sort * ty
|
|||
m_vectors.push_back(r);
|
||||
m_datatype2constructors.insert(ty, r);
|
||||
unsigned tid = ty->get_parameter(1).get_int();
|
||||
unsigned o = ty->get_parameter(3 + 2*tid).get_int();
|
||||
unsigned o = datatype_decl_plugin::constructor_offset(ty, tid);
|
||||
unsigned num_constructors = ty->get_parameter(o).get_int();
|
||||
for (unsigned c_id = 0; c_id < num_constructors; c_id++) {
|
||||
func_decl * c = get_constructor(ty, c_id);
|
||||
|
@ -880,7 +927,7 @@ ptr_vector<func_decl> const * datatype_util::get_constructor_accessors(func_decl
|
|||
unsigned c_id = constructor->get_parameter(1).get_int();
|
||||
sort * datatype = constructor->get_range();
|
||||
unsigned tid = datatype->get_parameter(1).get_int();
|
||||
unsigned o = datatype->get_parameter(3 + 2*tid).get_int();
|
||||
unsigned o = datatype_decl_plugin::constructor_offset(datatype, tid);
|
||||
unsigned k_i = datatype->get_parameter(o + c_id + 1).get_int();
|
||||
unsigned num_accessors = datatype->get_parameter(k_i+2).get_int();
|
||||
parameter p[3] = { parameter(datatype), parameter(c_id), parameter(-1) };
|
||||
|
|
|
@ -100,10 +100,16 @@ public:
|
|||
Contract for sort:
|
||||
parameters[0] - (int) n - number of recursive types.
|
||||
parameters[1] - (int) i - index 0..n-1 of which type is defined.
|
||||
|
||||
|
||||
parameters[2] - (int) p - number of type parameters.
|
||||
|
||||
for j = 0..p-1
|
||||
parameters[3 + j] - (sort) s - type parameter
|
||||
|
||||
c_offset := 3 + p
|
||||
for j in 0..n-1
|
||||
parameters[2 + 2*j] - (symbol) name of the type
|
||||
parameters[2 + 2*j + 1] - (int) o - offset where the constructors are defined.
|
||||
parameters[c_offset + 2*j] - (symbol) name of the type
|
||||
parameters[c_offset + 2*j + 1] - (int) o - offset where the constructors are defined.
|
||||
|
||||
for each offset o at parameters[2 + 2*j + 1] for some j in 0..n-1
|
||||
parameters[o] - (int) m - number of constructors
|
||||
|
@ -140,7 +146,7 @@ public:
|
|||
virtual func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
|
||||
unsigned arity, sort * const * domain, sort * range);
|
||||
|
||||
bool mk_datatypes(unsigned num_datatypes, datatype_decl * const * datatypes, sort_ref_vector & new_sorts);
|
||||
bool mk_datatypes(unsigned num_datatypes, datatype_decl * const * datatypes, unsigned num_params, sort* const* sort_params, sort_ref_vector & new_sorts);
|
||||
|
||||
virtual expr * get_some_value(sort * s);
|
||||
|
||||
|
@ -152,6 +158,13 @@ public:
|
|||
|
||||
virtual void get_op_names(svector<builtin_name> & op_names, symbol const & logic);
|
||||
|
||||
static unsigned constructor_offset(sort const* s);
|
||||
static unsigned constructor_offset(parameter const& p);
|
||||
static unsigned constructor_offset(parameter const* ps);
|
||||
|
||||
static unsigned constructor_offset(sort const* s, unsigned tid);
|
||||
static unsigned constructor_offset(parameter const* ps, unsigned tid);
|
||||
|
||||
private:
|
||||
bool is_value_visit(expr * arg, ptr_buffer<app> & todo) const;
|
||||
|
||||
|
@ -201,9 +214,18 @@ public:
|
|||
unsigned get_datatype_num_constructors(sort * ty) {
|
||||
SASSERT(is_datatype(ty));
|
||||
unsigned tid = ty->get_parameter(1).get_int();
|
||||
unsigned o = ty->get_parameter(3 + 2 * tid).get_int();
|
||||
unsigned o = datatype_decl_plugin::constructor_offset(ty, tid);
|
||||
return ty->get_parameter(o).get_int();
|
||||
}
|
||||
unsigned get_datatype_num_parameter_sorts(sort * ty) {
|
||||
SASSERT(is_datatype(ty));
|
||||
return ty->get_parameter(2).get_int();
|
||||
}
|
||||
sort* get_datatype_parameter_sort(sort * ty, unsigned idx) {
|
||||
SASSERT(is_datatype(ty));
|
||||
SASSERT(idx < get_datatype_num_parameter_sorts(ty));
|
||||
return to_sort(ty->get_parameter(3 + idx).get_ast());
|
||||
}
|
||||
unsigned get_constructor_idx(func_decl * f) const { SASSERT(is_constructor(f)); return f->get_parameter(1).get_int(); }
|
||||
unsigned get_recognizer_constructor_idx(func_decl * f) const { SASSERT(is_recognizer(f)); return f->get_parameter(1).get_int(); }
|
||||
func_decl * get_non_rec_constructor(sort * ty);
|
||||
|
@ -218,6 +240,7 @@ public:
|
|||
void reset();
|
||||
void display_datatype(sort *s, std::ostream& strm);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif /* DATATYPE_DECL_PLUGIN_H_ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue