Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
z3-z3-4.12.6.src.ast.dl_decl_plugin.cpp Maven / Gradle / Ivy
/*++
Copyright (c) 2010 Microsoft Corporation
Module Name:
dl_decl_plugin.h
Abstract:
Author:
Nikolaj Bjorner (nbjorner) 2010-04-10
Revision History:
--*/
#include
#include "ast/ast_pp.h"
#include "ast/array_decl_plugin.h"
#include "ast/datatype_decl_plugin.h"
#include "ast/dl_decl_plugin.h"
#include "util/warning.h"
#include "ast/reg_decl_plugins.h"
namespace datalog {
dl_decl_plugin::dl_decl_plugin() :
m_store_sym("store"),
m_empty_sym("empty"),
m_is_empty_sym("is_empty"),
m_join_sym("join"),
m_union_sym("union"),
m_widen_sym("widen"),
m_project_sym("project"),
m_filter_sym("filter"),
m_negation_filter_sym("negation_filter"),
m_rename_sym("rename"),
m_complement_sym("complement"),
m_select_sym("select"),
m_clone_sym("clone"),
m_num_sym("N"),
m_lt_sym("<"),
m_le_sym("<="),
m_rule_sym("R")
{
}
bool dl_decl_plugin::check_bounds(char const* msg, unsigned low, unsigned up, unsigned val) const {
if (low <= val && val <= up) {
return true;
}
std::ostringstream buffer;
buffer << msg << ", value is not within bound " << low << " <= " << val << " <= " << up;
m_manager->raise_exception(buffer.str());
return false;
}
bool dl_decl_plugin::check_domain(unsigned low, unsigned up, unsigned val) const {
return check_bounds("unexpected number of arguments", low, up, val);
}
bool dl_decl_plugin::check_params(unsigned low, unsigned up, unsigned val) const {
return check_bounds("unexpected number of parameters", low, up, val);
}
sort * dl_decl_plugin::mk_relation_sort( unsigned num_parameters, parameter const * parameters) {
bool is_finite = true;
rational r(1);
for (unsigned i = 0; is_finite && i < num_parameters; ++i) {
if (!parameters[i].is_ast() || !is_sort(parameters[i].get_ast())) {
m_manager->raise_exception("expecting sort parameters");
return nullptr;
}
sort* s = to_sort(parameters[i].get_ast());
sort_size const& sz1 = s->get_num_elements();
if (sz1.is_finite()) {
r *= rational(sz1.size(),rational::ui64());
}
else {
is_finite = false;
}
}
sort_size sz;
if (is_finite && r.is_uint64()) {
sz = sort_size::mk_finite(r.get_uint64());
}
else {
sz = sort_size::mk_very_big();
}
sort_info info(m_family_id, DL_RELATION_SORT, sz, num_parameters, parameters);
return m_manager->mk_sort(symbol("Table"),info);
}
sort * dl_decl_plugin::mk_finite_sort(unsigned num_params, parameter const* params) {
if (num_params != 2) {
m_manager->raise_exception("expecting two parameters");
return nullptr;
}
if (!params[0].is_symbol()) {
m_manager->raise_exception("expecting symbol");
return nullptr;
}
if (!params[1].is_rational() || !params[1].get_rational().is_uint64()) {
m_manager->raise_exception("expecting rational");
return nullptr;
}
sort_size sz = sort_size::mk_finite(params[1].get_rational().get_uint64());
sort_info info(m_family_id, DL_FINITE_SORT, sz, num_params, params);
return m_manager->mk_sort(params[0].get_symbol(),info);
}
sort* dl_decl_plugin::mk_rule_sort() {
sort_size sz(sort_size::mk_infinite());
sort_info info(m_family_id, DL_RULE_SORT, sz, 0, nullptr);
return m_manager->mk_sort(m_rule_sym, info);
}
sort * dl_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) {
switch(k) {
case DL_RELATION_SORT:
return mk_relation_sort(num_parameters, parameters);
case DL_FINITE_SORT:
return mk_finite_sort(num_parameters, parameters);
case DL_RULE_SORT:
return mk_rule_sort();
default:
UNREACHABLE();
}
return nullptr;
}
bool dl_decl_plugin::is_rel_sort(sort* r) {
ptr_vector sorts;
return is_rel_sort(r, sorts);
}
bool dl_decl_plugin::is_rel_sort(sort* r, ptr_vector& sorts) {
if (!is_sort_of(r, m_family_id, DL_RELATION_SORT)) {
m_manager->raise_exception("expected relation sort");
return false;
}
unsigned n = r->get_num_parameters();
for (unsigned i = 0; i < n; ++i) {
parameter const& p = r->get_parameter(i);
if (!p.is_ast() || !is_sort(p.get_ast())) {
m_manager->raise_exception("expected sort parameter");
return false;
}
sorts.push_back(to_sort(p.get_ast()));
}
return true;
}
bool dl_decl_plugin::is_fin_sort(sort* r) {
if (!is_sort_of(r, m_family_id, DL_FINITE_SORT)) {
m_manager->raise_exception("expected finite sort");
return false;
}
return true;
}
func_decl* dl_decl_plugin::mk_store_select(decl_kind k, unsigned arity, sort* const* domain) {
bool is_store = (k == OP_RA_STORE);
ast_manager& m = *m_manager;
symbol sym = is_store?m_store_sym:m_select_sym;
sort * r = domain[0];
if (!is_store) {
r = m.mk_bool_sort();
}
ptr_vector sorts;
if (!is_rel_sort(r, sorts)) {
return nullptr;
}
if (sorts.size() + 1 != arity) {
m_manager->raise_exception("wrong arity supplied to relational access");
return nullptr;
}
for (unsigned i = 0; i < sorts.size(); ++i) {
if (sorts[i] != domain[i+1]) {
IF_VERBOSE(0,
verbose_stream() << "Domain: " << mk_pp(domain[0], m) << "\n" <<
mk_pp(sorts[i], m) << "\n" <<
mk_pp(domain[i+1], m) << "\n";);
m_manager->raise_exception("sort mismatch for relational access");
return nullptr;
}
}
func_decl_info info(m_family_id, k, 0, nullptr);
return m.mk_func_decl(sym, arity, domain, r, info);
}
func_decl * dl_decl_plugin::mk_empty(parameter const& p) {
ast_manager& m = *m_manager;
if (!p.is_ast() || !is_sort(p.get_ast())) {
m_manager->raise_exception("expected sort parameter");
return nullptr;
}
sort* r = to_sort(p.get_ast());
if (!is_rel_sort(r)) {
return nullptr;
}
func_decl_info info(m_family_id, OP_RA_EMPTY, 1, &p);
return m.mk_func_decl(m_empty_sym, 0, (sort*const*)nullptr, r, info);
}
func_decl* dl_decl_plugin::mk_project(unsigned num_params, parameter const* params, sort* r) {
ast_manager& m = *m_manager;
ptr_vector sorts;
vector ps;
TRACE("dl_decl_plugin",
tout << mk_pp(r, m) << " ";
for (unsigned i = 0; i < num_params; ++i) {
tout << params[i] << " ";
}
tout << "\n";
);
if (!is_rel_sort(r, sorts)) {
return nullptr;
}
SASSERT(sorts.size() >= num_params);
// populate ps
unsigned j = 0, i = 0;
for (; i < num_params; ++i) {
if (!params[i].is_int()) {
m_manager->raise_exception("expecting integer parameter");
return nullptr;
}
unsigned k = params[i].get_int();
if (j > k) {
m_manager->raise_exception("arguments to projection should be increasing");
return nullptr;
}
while (j < k) {
ps.push_back(parameter(sorts[j]));
++j;
}
++j;
}
for (; j < sorts.size(); ++j) {
ps.push_back(parameter(sorts[j]));
}
SASSERT(ps.size() + num_params == sorts.size());
sort* r2 = m.mk_sort(m_family_id, DL_RELATION_SORT, ps.size(), ps.data());
func_decl_info info(m_family_id, OP_RA_PROJECT, num_params, params);
return m.mk_func_decl(m_project_sym, 1, &r, r2, info);
}
func_decl * dl_decl_plugin::mk_unionw(decl_kind k, sort* s1, sort* s2) {
ast_manager& m = *m_manager;
if (s1 != s2) {
m_manager->raise_exception("sort mismatch for arguments to union");
return nullptr;
}
if (!is_rel_sort(s1)) {
return nullptr;
}
sort* domain[2] = { s1, s2 };
func_decl_info info(m_family_id, k, 0, nullptr);
return m.mk_func_decl(m_union_sym, 2, domain, s1, info);
}
func_decl * dl_decl_plugin::mk_filter(parameter const& p, sort* r) {
ast_manager& m = *m_manager;
ptr_vector sorts;
if (!is_rel_sort(r, sorts)) {
return nullptr;
}
if (!p.is_ast() || !is_expr(p.get_ast())) {
m_manager->raise_exception("ast expression expected to filter");
}
expr* f = to_expr(p.get_ast());
// 1. f is of Boolean type.
// 2. the free variables in f correspond to column types of r.
if (!m.is_bool(f)) {
m_manager->raise_exception("filter predicate should be of Boolean type");
return nullptr;
}
ptr_vector todo;
todo.push_back(f);
ast_mark mark;
while (!todo.empty()) {
expr* e = todo.back();
todo.pop_back();
if (mark.is_marked(e)) {
continue;
}
mark.mark(e, true);
unsigned idx;
switch(e->get_kind()) {
case AST_VAR:
idx = to_var(e)->get_idx();
if (idx >= sorts.size()) {
m_manager->raise_exception("illegal index");
return nullptr;
}
if (sorts[idx] != e->get_sort()) {
m_manager->raise_exception("sort mismatch in filter");
return nullptr;
}
break;
case AST_APP:
for (unsigned i = 0; i < to_app(e)->get_num_args(); ++i) {
todo.push_back(to_app(e)->get_arg(i));
}
break;
case AST_QUANTIFIER:
m_manager->raise_exception("quantifiers are not allowed in filter expressions");
return nullptr;
default:
m_manager->raise_exception("unexpected filter expression kind");
return nullptr;
}
}
func_decl_info info(m_family_id, OP_RA_FILTER, 1, &p);
return m.mk_func_decl(m_filter_sym, 1, &r, r, info);
}
func_decl * dl_decl_plugin::mk_rename(unsigned num_params, parameter const* params, sort* r) {
ptr_vector sorts;
if (!is_rel_sort(r, sorts)) {
return nullptr;
}
unsigned index0 = 0;
sort* last_sort = nullptr;
SASSERT(num_params > 0);
for (unsigned i = 0; i < num_params; ++i) {
parameter const& p = params[i];
if (!p.is_int()) {
m_manager->raise_exception("expected integer parameter");
return nullptr;
}
unsigned j = p.get_int();
if (j >= sorts.size()) {
// We should not use ast_pp anymore on error messages.
// m_manager->raise_exception("index %d out of bound %s : %d", j, ast_pp(r, *m_manager).c_str(), sorts.size());
m_manager->raise_exception("index out of bound");
return nullptr;
}
if (i == 0) {
index0 = j;
last_sort = sorts[j];
}
else {
std::swap(last_sort, sorts[j]);
}
}
sorts[index0] = last_sort;
vector params2;
for (unsigned i = 0; i < sorts.size(); ++i) {
params2.push_back(parameter(sorts[i]));
}
sort* rng = m_manager->mk_sort(m_family_id, DL_RELATION_SORT, params2.size(), params2.data());
func_decl_info info(m_family_id, OP_RA_RENAME, num_params, params);
return m_manager->mk_func_decl(m_rename_sym, 1, &r, rng, info);
}
func_decl * dl_decl_plugin::mk_join(unsigned num_params, parameter const* params, sort* r1, sort* r2) {
vector params2;
ptr_vector sorts1, sorts2;
if (!is_rel_sort(r1, sorts1)) {
return nullptr;
}
if (!is_rel_sort(r2, sorts2)) {
return nullptr;
}
for (unsigned i = 0; i < sorts1.size(); ++i) {
params2.push_back(parameter(sorts1[i]));
}
for (unsigned i = 0; i < sorts2.size(); ++i) {
params2.push_back(parameter(sorts2[i]));
}
if (0 != num_params % 2) {
m_manager->raise_exception("expecting an even number of parameters to join");
return nullptr;
}
for (unsigned i = 0; i + 1 < num_params; i += 2) {
parameter const& p1 = params[i];
parameter const& p2 = params[i+1];
if (!p1.is_int() || !p2.is_int()) {
m_manager->raise_exception("encountered non-integer parameter");
return nullptr;
}
unsigned i1 = p1.get_int();
unsigned i2 = p2.get_int();
if (i1 >= sorts1.size() || i2 >= sorts2.size()) {
m_manager->raise_exception("index out of bounds");
return nullptr;
}
if (sorts1[i1] != sorts2[i2]) {
m_manager->raise_exception("sort mismatch in join");
return nullptr;
}
}
sort* args[2] = { r1, r2 };
sort* rng = m_manager->mk_sort(m_family_id, DL_RELATION_SORT, params2.size(), params2.data());
func_decl_info info(m_family_id, OP_RA_JOIN, num_params, params);
return m_manager->mk_func_decl(m_join_sym, 2, args, rng, info);
}
func_decl* dl_decl_plugin::mk_complement(sort* s) {
if (!is_rel_sort(s)) {
return nullptr;
}
func_decl_info info(m_family_id, OP_RA_COMPLEMENT, 0, nullptr);
return m_manager->mk_func_decl(m_complement_sym, 1, &s, s, info);
}
func_decl * dl_decl_plugin::mk_negation_filter(unsigned num_params, parameter const* params, sort* r1, sort* r2) {
ptr_vector sorts1, sorts2;
if (!is_rel_sort(r1, sorts1)) {
return nullptr;
}
if (!is_rel_sort(r2, sorts2)) {
return nullptr;
}
if (0 != num_params % 2) {
m_manager->raise_exception("expecting an even number of parameters to negation filter");
return nullptr;
}
for (unsigned i = 0; i + 1 < num_params; i += 2) {
parameter const& p1 = params[i];
parameter const& p2 = params[i+1];
if (!p1.is_int() || !p2.is_int()) {
m_manager->raise_exception("encountered non-integer parameter");
return nullptr;
}
unsigned i1 = p1.get_int();
unsigned i2 = p2.get_int();
if (i1 >= sorts1.size() || i2 >= sorts2.size()) {
m_manager->raise_exception("index out of bounds");
return nullptr;
}
if (sorts1[i1] != sorts2[i2]) {
m_manager->raise_exception("sort mismatch in join");
return nullptr;
}
}
sort* args[2] = { r1, r2 };
func_decl_info info(m_family_id, OP_RA_NEGATION_FILTER, num_params, params);
return m_manager->mk_func_decl(m_negation_filter_sym, 2, args, r1, info);
}
func_decl * dl_decl_plugin::mk_is_empty(sort* s) {
if (!is_rel_sort(s)) {
return nullptr;
}
func_decl_info info(m_family_id, OP_RA_IS_EMPTY, 0, nullptr);
sort* rng = m_manager->mk_bool_sort();
return m_manager->mk_func_decl(m_is_empty_sym, 1, &s, rng, info);
}
func_decl * dl_decl_plugin::mk_constant(parameter const* params) {
parameter const& p = params[0];
parameter const& ps = params[1];
if (!p.is_rational() || !p.get_rational().is_uint64()) {
m_manager->raise_exception("first parameter should be a rational");
return nullptr;
}
if (!ps.is_ast() || !is_sort(ps.get_ast()) || !is_fin_sort(to_sort(ps.get_ast()))) {
m_manager->raise_exception("second parameter should be a finite domain sort");
return nullptr;
}
sort* s = to_sort(ps.get_ast());
func_decl_info info(m_family_id, OP_DL_CONSTANT, 2, params);
return m_manager->mk_func_decl(m_num_sym, 0, (sort*const*)nullptr, s, info);
}
func_decl * dl_decl_plugin::mk_compare(decl_kind k, symbol const& sym, sort *const* domain) {
if (!is_sort_of(domain[0], m_family_id, DL_FINITE_SORT)) {
m_manager->raise_exception("expecting finite domain sort");
return nullptr;
}
if (domain[0] != domain[1]) {
m_manager->raise_exception("expecting two identical finite domain sorts");
return nullptr;
}
func_decl_info info(m_family_id, k, 0, nullptr);
return m_manager->mk_func_decl(sym, 2, domain, m_manager->mk_bool_sort(), info);
}
func_decl * dl_decl_plugin::mk_clone(sort* s) {
if (!is_rel_sort(s)) {
return nullptr;
}
func_decl_info info(m_family_id, OP_RA_CLONE, 0, nullptr);
return m_manager->mk_func_decl(m_clone_sym, 1, &s, s, info);
}
func_decl * dl_decl_plugin::mk_func_decl(
decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned arity, sort * const * domain, sort * range) {
func_decl* result = nullptr;
switch(k) {
case OP_RA_STORE:
case OP_RA_SELECT:
if (!check_params(0, 0, num_parameters) ||
!check_domain(1, UINT_MAX, arity)) {
return nullptr;
}
result = mk_store_select(k, arity, domain);
break;
case OP_RA_EMPTY:
if (!check_params( 1, 1, num_parameters) ||
!check_domain(0, 0, arity)) {
return nullptr;
}
result = mk_empty(parameters[0]);
break;
case OP_RA_JOIN:
if (!check_params(0, UINT_MAX, num_parameters) ||
!check_domain(2, 2, arity)) {
return nullptr;
}
result = mk_join(num_parameters, parameters, domain[0], domain[1]);
break;
case OP_RA_UNION:
case OP_RA_WIDEN:
if (!check_params( 0, 0, num_parameters) ||
!check_domain(2, 2, arity)) {
return nullptr;
}
result = mk_unionw(k, domain[0], domain[1]);
break;
case OP_RA_PROJECT:
if (!check_params( 1, UINT_MAX, num_parameters) ||
!check_domain(1, 1, arity)) {
return nullptr;
}
result = mk_project(num_parameters, parameters, domain[0]);
break;
case OP_RA_FILTER:
if (!check_params( 1, 1, num_parameters) ||
!check_domain(1, 1, arity)) {
return nullptr;
}
result = mk_filter(parameters[0], domain[0]);
break;
case OP_RA_IS_EMPTY:
if (!check_params( 0, 0, num_parameters) ||
!check_domain(1, 1, arity)) {
return nullptr;
}
result = mk_is_empty(domain[0]);
break;
case OP_RA_RENAME:
if (!check_params( 2, UINT_MAX, num_parameters) ||
!check_domain(1, 1, arity)) {
return nullptr;
}
result = mk_rename(num_parameters, parameters, domain[0]);
break;
case OP_RA_COMPLEMENT:
if (!check_params( 0, 0, num_parameters) ||
!check_domain(1, 1, arity)) {
return nullptr;
}
result = mk_complement(domain[0]);
break;
case OP_RA_NEGATION_FILTER:
if (!check_params(1, UINT_MAX, num_parameters) ||
!check_domain(2, 2, arity)) {
return nullptr;
}
result = mk_negation_filter(num_parameters, parameters, domain[0], domain[1]);
break;
case OP_RA_CLONE:
if (!check_params(0, 0, num_parameters) || !check_domain(1, 1, arity)) {
return nullptr;
}
result = mk_clone(domain[0]);
break;
case OP_DL_CONSTANT:
if (!check_params( 2, 2, num_parameters) ||
!check_domain(0, 0, arity)) {
return nullptr;
}
result = mk_constant(parameters);
break;
case OP_DL_LT:
if (!check_params( 0, 0, num_parameters) ||
!check_domain(2, 2, arity)) {
return nullptr;
}
result = mk_compare(OP_DL_LT, m_lt_sym, domain);
break;
case OP_DL_REP: {
if (!check_domain(0, 0, num_parameters) ||
!check_domain(1, 1, arity)) return nullptr;
func_decl_info info(m_family_id, k, 0, nullptr);
result = m_manager->mk_func_decl(symbol("rep"), 1, domain, range, info);
break;
}
case OP_DL_ABS: {
if (!check_domain(0, 0, num_parameters) ||
!check_domain(1, 1, arity)) return nullptr;
func_decl_info info(m_family_id, k, 0, nullptr);
result = m_manager->mk_func_decl(symbol("abs"), 1, domain, range, info);
break;
}
default:
m_manager->raise_exception("operator not recognized");
return nullptr;
}
TRACE("dl_decl_plugin", tout << mk_pp(result, *m_manager) << "\n";);
return result;
}
void dl_decl_plugin::get_op_names(svector & op_names, symbol const & logic) {
}
void dl_decl_plugin::get_sort_names(svector & sort_names, symbol const & logic) {
}
dl_decl_util::dl_decl_util(ast_manager& m):
m(m),
m_fid(null_family_id)
{}
bv_util& dl_decl_util::bv() const {
if (!m_bv) m_bv = alloc(bv_util, m);
return *m_bv;
}
family_id dl_decl_util::get_family_id() const {
if (m_fid == null_family_id) {
m_fid = m.mk_family_id(symbol("datalog_relation"));
}
return m_fid;
};
arith_util& dl_decl_util::arith() const {
if (!m_arith) m_arith = alloc(arith_util, m);
return *m_arith;
}
// create a constant belonging to a given finite domain.
app* dl_decl_util::mk_numeral(uint64_t value, sort* s) {
if (is_finite_sort(s)) {
uint64_t sz = 0;
if (try_get_size(s, sz) && sz <= value) {
m.raise_exception("value is out of bounds");
}
parameter params[2] = { parameter(rational(value, rational::ui64())), parameter(s) };
return m.mk_const(m.mk_func_decl(get_family_id(), OP_DL_CONSTANT, 2, params, 0, (sort*const*)nullptr));
}
if (arith().is_int(s) || arith().is_real(s)) {
return arith().mk_numeral(rational(value, rational::ui64()), s);
}
if (bv().is_bv_sort(s)) {
return bv().mk_numeral(rational(value, rational::ui64()), s);
}
if (m.is_bool(s)) {
if (value == 0) {
return m.mk_false();
}
SASSERT(value == 1);
return m.mk_true();
}
std::stringstream strm;
strm << "sort '" << mk_pp(s, m) << "' is not recognized as a sort that contains numeric values.\nUse Bool, BitVec, Int, Real, or a Finite domain sort";
m.raise_exception(strm.str());
return nullptr;
}
bool dl_decl_util::is_numeral(const expr* e, uint64_t& v) const {
if (is_numeral(e)) {
const app* c = to_app(e);
SASSERT(c->get_decl()->get_num_parameters() == 2);
parameter const& p = c->get_decl()->get_parameter(0);
SASSERT(p.is_rational());
SASSERT(p.get_rational().is_uint64());
v = p.get_rational().get_uint64();
return true;
}
return false;
}
bool dl_decl_util::is_numeral_ext(expr* e, uint64_t& v) const {
if (is_numeral(e, v))
return true;
if (m.is_true(e)) {
v = 1;
return true;
}
if (m.is_false(e)) {
v = 0;
return true;
}
rational val;
unsigned bv_size = 0;
if (bv().is_numeral(e, val, bv_size) && bv_size < 64) {
SASSERT(val.is_uint64());
v = val.get_uint64();
return true;
}
datatype::util dt(m);
if (dt.is_enum_sort(e->get_sort()) && dt.is_constructor(e)) {
auto& cs = *dt.get_datatype_constructors(e->get_sort());
v = 0;
for (func_decl* f : cs) {
if (f == to_app(e)->get_decl())
return true;
++v;
}
}
return false;
}
bool dl_decl_util::is_numeral_ext(expr* c) const {
if (is_numeral(c))
return true;
rational val;
unsigned bv_size = 0;
if (arith().is_numeral(c, val) && val.is_uint64())
return true;
if (bv().is_numeral(c, val, bv_size) && bv_size < 64)
return true;
if (m.is_true(c) || m.is_false(c))
return true;
datatype::util dt(m);
if (dt.is_enum_sort(c->get_sort()) && dt.is_constructor(c))
return true;
return false;
}
sort* dl_decl_util::mk_sort(const symbol& name, uint64_t domain_size) {
if (domain_size == 0) {
std::stringstream sstm;
sstm << "Domain size of sort '" << name << "' may not be 0";
throw default_exception(sstm.str());
}
parameter params[2] = { parameter(name), parameter(rational(domain_size, rational::ui64())) };
return m.mk_sort(get_family_id(), DL_FINITE_SORT, 2, params);
}
bool dl_decl_util::try_get_size(const sort * s, uint64_t& size) const {
sort_size sz = s->get_info()->get_num_elements();
if (sz.is_finite()) {
size = sz.size();
return true;
}
return false;
}
app* dl_decl_util::mk_lt(expr* a, expr* b) {
expr* args[2] = { a, b };
return m.mk_app(get_family_id(), OP_DL_LT, 0, nullptr, 2, args);
}
app* dl_decl_util::mk_le(expr* a, expr* b) {
expr* args[2] = { b, a };
return m.mk_not(m.mk_app(get_family_id(), OP_DL_LT, 0, nullptr, 2, args));
}
sort* dl_decl_util::mk_rule_sort() {
return m.mk_sort(get_family_id(), DL_RULE_SORT);
}
app* dl_decl_util::mk_rule(symbol const& name, unsigned num_args, expr* const* args) {
ptr_buffer sorts;
for (unsigned i = 0; i < num_args; ++i) {
sorts.push_back(args[i]->get_sort());
}
func_decl* f = m.mk_func_decl(name, num_args, sorts.data(), mk_rule_sort());
return m.mk_app(f, num_args, args);
}
};