z3-z3-4.13.0.src.cmd_context.pdecl.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
pdecl.h
Abstract:
Parametric declarations for SMT-LIB 2.0 + inductive data-types.
Author:
Leonardo de Moura (leonardo) 2011-03-02.
Revision History:
--*/
#pragma once
#include "ast/ast.h"
#include "util/obj_hashtable.h"
#include "util/dictionary.h"
#include "ast/format.h"
#include "ast/datatype_decl_plugin.h"
#include "ast/ast_smt2_pp.h"
class pdecl_manager;
class pdecl {
protected:
friend class pdecl_manager;
unsigned m_id;
unsigned m_num_params;
unsigned m_ref_count;
void inc_ref() { m_ref_count++; }
void dec_ref() { SASSERT(m_ref_count > 0); --m_ref_count; }
virtual bool is_psort() const { return false; }
virtual size_t obj_size() const { UNREACHABLE(); return sizeof(*this); }
pdecl(unsigned id, unsigned num_params):m_id(id), m_num_params(num_params), m_ref_count(0) {}
virtual void finalize(pdecl_manager & m) {}
virtual ~pdecl() = default;
public:
virtual bool check_num_params(pdecl * other) const { return m_num_params == other->m_num_params; }
unsigned get_num_params() const { return m_num_params; }
unsigned get_id() const { return m_id; }
unsigned get_ref_count() const { return m_ref_count; }
unsigned hash() const { return m_id; }
virtual std::ostream& display(std::ostream & out) const { return out;}
virtual void reset_cache(pdecl_manager& m) {}
};
class psort_inst_cache;
#if defined(__APPLE__) && defined(__MACH__)
// CMW: for some unknown reason, llvm on macOS does not like the name `psort'
#define psort Z3_psort
#endif
/**
\brief Parametric sorts.
*/
class psort : public pdecl {
protected:
psort_inst_cache* m_inst_cache;
friend class pdecl_manager;
psort(unsigned id, unsigned num_params):pdecl(id, num_params), m_inst_cache(nullptr) {}
bool is_psort() const override { return true; }
void finalize(pdecl_manager & m) override;
virtual void cache(pdecl_manager & m, sort * const * s, sort * r);
virtual sort * find(sort * const * s) const;
public:
virtual bool is_sort_wrapper() const { return false; }
virtual sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s) { return nullptr; }
// we use hash-consing for psorts.
virtual char const * hcons_kind() const { UNREACHABLE(); return nullptr; }
virtual unsigned hcons_hash() const { UNREACHABLE(); return 0; }
virtual bool hcons_eq(psort const * other) const { UNREACHABLE(); return false; }
void reset_cache(pdecl_manager& m) override;
};
// for hash consing
struct psort_hash_proc { unsigned operator()(psort * p) const { return p->hcons_hash(); } };
struct psort_eq_proc { bool operator()(psort * p1, psort * p2) const { return p1->hcons_eq(p2); } };
typedef ptr_hashtable psort_table;
#define PSORT_DECL_VAR_PARAMS UINT_MAX
typedef enum { PSORT_BASE = 0, PSORT_USER, PSORT_BUILTIN, PSORT_DT, PSORT_TV } psort_decl_kind;
class psort_decl : public pdecl {
protected:
friend class pdecl_manager;
symbol m_name;
psort_decl_kind m_psort_kind;
psort_inst_cache * m_inst_cache;
void cache(pdecl_manager & m, sort * const * s, sort * r);
sort * find(sort * const * s);
psort_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n);
void finalize(pdecl_manager & m) override;
public:
virtual sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s) = 0;
virtual sort * instantiate(pdecl_manager & m, unsigned n, unsigned const * s) { return nullptr; }
virtual sort * instantiate(pdecl_manager & m) { return instantiate(m, 0, static_cast(nullptr)); }
// return true if the declaration accepts a variable number of parameters.
// Only builtin declarations can have a variable number of parameters.
bool has_var_params() const { return m_num_params == PSORT_DECL_VAR_PARAMS; }
symbol const & get_name() const { return m_name; }
void reset_cache(pdecl_manager& m) override;
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 {
protected:
friend class pdecl_manager;
psort * m_def;
psort_user_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, psort * p);
size_t obj_size() const override { return sizeof(psort_user_decl); }
void finalize(pdecl_manager & m) override;
public:
sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s) override;
std::ostream& display(std::ostream & out) const override;
};
class psort_type_var_decl : public psort_decl {
protected:
friend class pdecl_manager;
psort * m_def;
psort_type_var_decl(unsigned id, pdecl_manager & m, symbol const & n);
size_t obj_size() const override { return sizeof(psort_type_var_decl); }
void finalize(pdecl_manager & m) override;
public:
sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s) override;
std::ostream& display(std::ostream & out) const override;
};
class psort_builtin_decl : public psort_decl {
protected:
friend class pdecl_manager;
family_id m_fid;
decl_kind m_kind;
psort_builtin_decl(unsigned id, pdecl_manager & m, symbol const & n, family_id fid, decl_kind k);
size_t obj_size() const override { return sizeof(psort_builtin_decl); }
public:
sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s) override;
sort * instantiate(pdecl_manager & m, unsigned n, unsigned const * s) override;
std::ostream& display(std::ostream & out) const override;
};
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);
size_t obj_size() const override { return sizeof(psort_dt_decl); }
public:
sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s) override;
std::ostream& display(std::ostream & out) const override;
};
class pdatatypes_decl;
class pdatatype_decl;
class pconstructor_decl;
class paccessor_decl;
enum class ptype_kind {
PTR_PSORT, // psort
PTR_REC_REF, // recursive reference
PTR_MISSING_REF // a symbol, it is useful for building parsers.
};
class ptype {
ptype_kind m_kind;
union {
psort * m_sort;
int m_idx;
};
symbol m_missing_ref;
public:
ptype():m_kind(ptype_kind::PTR_PSORT), m_sort(nullptr) {}
ptype(int idx):m_kind(ptype_kind::PTR_REC_REF), m_idx(idx) {}
ptype(psort * s):m_kind(ptype_kind::PTR_PSORT), m_sort(s) {}
ptype(symbol const & s):m_kind(ptype_kind::PTR_MISSING_REF), m_sort(nullptr), m_missing_ref(s) {}
ptype_kind kind() const { return m_kind; }
psort * get_psort() const { SASSERT(kind() == ptype_kind::PTR_PSORT); return m_sort; }
int get_idx() const { SASSERT(kind() == ptype_kind::PTR_REC_REF); return m_idx; }
symbol const & get_missing_ref() const { SASSERT(kind() == ptype_kind::PTR_MISSING_REF); return m_missing_ref; }
void display(std::ostream & out, pdatatype_decl const * const * dts) const;
};
class paccessor_decl : public pdecl {
friend class pdecl_manager;
friend class pconstructor_decl;
friend class pdatatype_decl;
symbol m_name;
ptype m_type;
paccessor_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, ptype const & r);
void finalize(pdecl_manager & m) override;
size_t obj_size() const override { return sizeof(paccessor_decl); }
bool has_missing_refs(symbol & missing) const;
bool fix_missing_refs(dictionary const & symbol2idx, symbol & missing);
accessor_decl * instantiate_decl(pdecl_manager & m, unsigned n, sort * const * s);
symbol const & get_name() const { return m_name; }
ptype const & get_type() const { return m_type; }
public:
std::ostream& display(std::ostream & out) const override { pdecl::display(out); return out; }
void display(std::ostream & out, pdatatype_decl const * const * dts) const;
};
class pconstructor_decl : public pdecl {
friend class pdecl_manager;
friend class pdatatype_decl;
symbol m_name;
symbol m_recogniser_name;
ptr_vector m_accessors;
pconstructor_decl(unsigned id, unsigned num_params, pdecl_manager & m,
symbol const & n, symbol const & r, unsigned num_accessors, paccessor_decl * const * accessors);
void finalize(pdecl_manager & m) override;
size_t obj_size() const override { return sizeof(pconstructor_decl); }
bool has_missing_refs(symbol & missing) const;
bool fix_missing_refs(dictionary const & symbol2idx, symbol & missing);
symbol const & get_name() const { return m_name; }
symbol const & get_recognizer_name() const { return m_recogniser_name; }
constructor_decl * instantiate_decl(pdecl_manager & m, unsigned n, sort * const * s);
public:
std::ostream& display(std::ostream & out) const override { pdecl::display(out); return out; }
void display(std::ostream & out, pdatatype_decl const * const * dts) const;
};
class pdatatype_decl : public psort_decl {
friend class pdecl_manager;
friend class pdatatypes_decl;
ptr_vector m_constructors;
pdatatypes_decl * m_parent;
pdatatype_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n,
unsigned num_constructors, pconstructor_decl * const * constructors);
void finalize(pdecl_manager & m) override;
size_t obj_size() const override { return sizeof(pdatatype_decl); }
bool fix_missing_refs(dictionary const & symbol2idx, symbol & missing);
datatype_decl * instantiate_decl(pdecl_manager & m, unsigned n, sort * const * s);
public:
sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s) override;
std::ostream& display(std::ostream & out) const override;
bool has_missing_refs(symbol & missing) const;
bool has_duplicate_accessors(symbol & repeated) const;
bool commit(pdecl_manager& m);
};
/**
\brief Represents a set of parametric mutually recursive inductive data-types.
*/
class pdatatypes_decl : public pdecl {
friend class pdecl_manager;
friend class pdatatype_decl;
ptr_vector m_datatypes;
pdatatypes_decl(unsigned id, unsigned num_params, pdecl_manager & m, unsigned num_datatypes, pdatatype_decl * const * dts);
void finalize(pdecl_manager & m) override;
size_t obj_size() const override { return sizeof(pdatatypes_decl); }
bool fix_missing_refs(symbol & missing);
bool instantiate(pdecl_manager & m, sort * const * s);
public:
pdatatype_decl const * const * children() const { return m_datatypes.data(); }
pdatatype_decl * const * begin() const { return m_datatypes.begin(); }
pdatatype_decl * const * end() const { return m_datatypes.end(); }
// commit declaration
bool commit(pdecl_manager& m);
};
class new_datatype_eh {
public:
virtual ~new_datatype_eh() = default;
virtual void operator()(sort * dt, pdecl* pd) = 0;
};
class pdecl_manager {
ast_manager & m_manager;
small_object_allocator & m_allocator;
id_gen m_id_gen;
obj_map m_sort2psort;
psort_table m_table;
ptr_vector m_to_delete;
pdatatype_decl * m_list;
family_id m_datatype_fid;
new_datatype_eh * m_new_dt_eh;
struct sort_info;
struct app_sort_info;
struct indexed_sort_info;
obj_map m_sort2info; // for pretty printing sorts
obj_hashtable m_notified;
ptr_vector m_notified_trail;
unsigned_vector m_notified_lim;
svector m_datatypes_trail;
unsigned_vector m_datatypes_lim;
void init_list();
void del_decl_core(pdecl * p);
void del_decl(pdecl * p);
void del_decls();
psort * register_psort(psort * n);
void reset_sort_info();
public:
pdecl_manager(ast_manager & m);
~pdecl_manager();
ast_manager & m() const { return m_manager; }
small_object_allocator & a() const { return m_allocator; }
family_id get_datatype_fid() const { return m_datatype_fid; }
void set_new_datatype_eh(new_datatype_eh * eh) { m_new_dt_eh = eh; }
psort * mk_psort_cnst(sort * s);
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_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);
psort_decl * mk_psort_type_var_decl(symbol const& n);
paccessor_decl * mk_paccessor_decl(unsigned num_params, symbol const & s, ptype const & p);
pconstructor_decl * mk_pconstructor_decl(unsigned num_params, symbol const & s, symbol const & r, unsigned num, paccessor_decl * const * as);
pdatatype_decl * mk_pdatatype_decl(unsigned num_params, symbol const & s, unsigned num, pconstructor_decl * const * cs);
pdatatypes_decl * mk_pdatatypes_decl(unsigned num_params, unsigned num, pdatatype_decl * const * dts);
pdatatype_decl * mk_plist_decl() { if (!m_list) init_list(); return m_list; }
bool fix_missing_refs(pdatatypes_decl * s, symbol & missing) { return s->fix_missing_refs(missing); }
sort * instantiate_datatype(psort_decl* p, symbol const& name, unsigned n, sort * const* s);
sort * instantiate(psort * s, unsigned num, sort * const * args);
void notify_datatype(sort *r, psort_decl* p, unsigned n, sort* const* s);
void notify_mk_datatype(symbol const& name);
void push();
void pop(unsigned n);
void lazy_dec_ref(pdecl * p) { p->dec_ref(); if (p->get_ref_count() == 0) m_to_delete.push_back(p); }
template
void lazy_dec_ref(unsigned num, T * const * ps) { for (unsigned i = 0; i < num; i++) lazy_dec_ref(ps[i]); }
void inc_ref(pdecl * p) { if (p) { p->inc_ref(); } }
void dec_ref(pdecl * p) { if (p) { lazy_dec_ref(p); del_decls(); } }
template
void inc_ref(unsigned num, T * const * ps) { for (unsigned i = 0; i < num; i++) inc_ref(ps[i]); }
template
void dec_ref(unsigned num, T * const * ps) { lazy_dec_ref(num, ps); del_decls(); }
psort_inst_cache * mk_inst_cache(unsigned num_params);
void del_inst_cache(psort_inst_cache * c);
void notify_new_dt(sort * dt, pdecl* pd) { if (m_new_dt_eh) (*m_new_dt_eh)(dt, pd); }
datatype_decl_plugin * get_dt_plugin() const;
void save_info(sort * s, psort_decl * d, unsigned num_args, sort * const * args);
void save_info(sort * s, psort_decl * d, unsigned num_indices, unsigned const * indices);
void display(std::ostream & out, sort * s) const;
format_ns::format * pp(smt2_pp_environment& env, sort * s) const;
};
typedef obj_ref pdecl_ref;
typedef obj_ref psort_ref;
typedef obj_ref paccessor_decl_ref;
typedef obj_ref pconstructor_decl_ref;
typedef obj_ref pdatatype_decl_ref;
typedef obj_ref pdatatypes_decl_ref;
typedef ref_vector pdecl_ref_vector;
typedef ref_vector psort_decl_ref_vector;
typedef ref_vector psort_ref_vector;
typedef ref_buffer paccessor_decl_ref_buffer;
typedef ref_buffer pconstructor_decl_ref_buffer;
typedef ref_buffer pdatatype_decl_ref_buffer;
typedef ref_buffer pdatatypes_decl_ref_buffer;