diff --git a/src/ast/datatype_decl_plugin.h b/src/ast/datatype_decl_plugin.h index 3b4c8dd08..840329dda 100644 --- a/src/ast/datatype_decl_plugin.h +++ b/src/ast/datatype_decl_plugin.h @@ -16,7 +16,7 @@ Author: Revision History: --*/ -// define DATATYPE_V2 +#define DATATYPE_V2 #ifdef DATATYPE_V2 #include "ast/datatype_decl_plugin2.h" #else diff --git a/src/ast/datatype_decl_plugin2.cpp b/src/ast/datatype_decl_plugin2.cpp index 41ae2e839..fa3c73bca 100644 --- a/src/ast/datatype_decl_plugin2.cpp +++ b/src/ast/datatype_decl_plugin2.cpp @@ -236,7 +236,7 @@ namespace datatype { return m.mk_func_decl(symbol("update-field"), arity, domain, range, info); } -#define VALIDATE_PARAM(_pred_) if (!(_pred_)) m_manager->raise_exception("invalid parameter to datatype function"); +#define VALIDATE_PARAM(_pred_) if (!(_pred_)) m_manager->raise_exception("invalid parameter to datatype function " #_pred_); func_decl * decl::plugin::mk_constructor(unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { @@ -252,13 +252,26 @@ namespace datatype { func_decl * decl::plugin::mk_recognizer(unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort *) { ast_manager& m = *m_manager; - VALIDATE_PARAM(arity == 1 && num_parameters == 1 && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); + VALIDATE_PARAM(arity == 1 && num_parameters == 2 && parameters[1].is_symbol() && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); VALIDATE_PARAM(u().is_datatype(domain[0])); // blindly trust that parameter is a constructor sort* range = m_manager->mk_bool_sort(); func_decl* f = to_func_decl(parameters[0].get_ast()); func_decl_info info(m_family_id, OP_DT_RECOGNISER, num_parameters, parameters); info.m_private_parameters = true; + return m.mk_func_decl(symbol(parameters[1].get_symbol()), arity, domain, range, info); + } + + func_decl * decl::plugin::mk_is(unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort *) { + ast_manager& m = *m_manager; + VALIDATE_PARAM(arity == 1 && num_parameters == 1 && parameters[0].is_ast() && is_func_decl(parameters[0].get_ast())); + VALIDATE_PARAM(u().is_datatype(domain[0])); + // blindly trust that parameter is a constructor + sort* range = m_manager->mk_bool_sort(); + func_decl* f = to_func_decl(parameters[0].get_ast()); + func_decl_info info(m_family_id, OP_DT_IS, num_parameters, parameters); + info.m_private_parameters = true; return m.mk_func_decl(symbol("is"), arity, domain, range, info); } @@ -282,6 +295,8 @@ namespace datatype { return mk_constructor(num_parameters, parameters, arity, domain, range); case OP_DT_RECOGNISER: return mk_recognizer(num_parameters, parameters, arity, domain, range); + case OP_DT_IS: + return mk_is(num_parameters, parameters, arity, domain, range); case OP_DT_ACCESSOR: return mk_accessor(num_parameters, parameters, arity, domain, range); case OP_DT_UPDATE_FIELD: @@ -297,20 +312,6 @@ namespace datatype { return alloc(def, m, u(), name, m_class_id, n, params); } -#if 0 - def& plugin::add(symbol const& name, unsigned n, sort * const * params) { - ast_manager& m = *m_manager; - def* d = 0; - if (m_defs.find(name, d)) { - TRACE("datatype", tout << "delete previous version for " << name << "\n";); - dealloc(d); - } - d = alloc(def, m, u(), name, m_class_id, n, params); - m_defs.insert(name, d); - m_def_block.push_back(name); - return *d; - } -#endif void plugin::end_def_block() { ast_manager& m = *m_manager; @@ -407,7 +408,7 @@ namespace datatype { } void plugin::get_op_names(svector & op_names, symbol const & logic) { - op_names.push_back(builtin_name("is", OP_DT_RECOGNISER)); + op_names.push_back(builtin_name("is", OP_DT_IS)); if (logic == symbol::null) { op_names.push_back(builtin_name("update-field", OP_DT_UPDATE_FIELD)); } @@ -739,18 +740,25 @@ namespace datatype { return res; } - func_decl * util::get_constructor_recognizer(func_decl * constructor) { - SASSERT(is_constructor(constructor)); + func_decl * util::get_constructor_recognizer(func_decl * con) { + SASSERT(is_constructor(con)); func_decl * d = 0; - if (m_constructor2recognizer.find(constructor, d)) + if (m_constructor2recognizer.find(con, d)) return d; - sort * datatype = constructor->get_range(); - parameter ps[1] = { parameter(constructor) }; - d = m.mk_func_decl(m_family_id, OP_DT_RECOGNISER, 1, ps, 1, &datatype); + sort * datatype = con->get_range(); + def const& dd = get_def(datatype); + symbol r; + for (constructor const* c : dd) { + if (c->name() == con->get_name()) { + r = c->recognizer(); + } + } + parameter ps[2] = { parameter(con), parameter(r) }; + d = m.mk_func_decl(m_family_id, OP_DT_RECOGNISER, 2, ps, 1, &datatype); SASSERT(d); - m_asts.push_back(constructor); + m_asts.push_back(con); m_asts.push_back(d); - m_constructor2recognizer.insert(constructor, d); + m_constructor2recognizer.insert(con, d); return d; } @@ -917,11 +925,11 @@ namespace datatype { UNREACHABLE(); return 0; } + unsigned util::get_recognizer_constructor_idx(func_decl * f) const { return get_constructor_idx(get_recognizer_constructor(f)); } - /** \brief Two datatype sorts s1 and s2 are siblings if they were defined together in the same mutually recursive definition. diff --git a/src/ast/datatype_decl_plugin2.h b/src/ast/datatype_decl_plugin2.h index d7173b24a..f076bb43f 100644 --- a/src/ast/datatype_decl_plugin2.h +++ b/src/ast/datatype_decl_plugin2.h @@ -36,7 +36,8 @@ Revision History: enum op_kind { OP_DT_CONSTRUCTOR, OP_DT_RECOGNISER, - OP_DT_ACCESSOR, + OP_DT_IS, + OP_DT_ACCESSOR, OP_DT_UPDATE_FIELD, LAST_DT_OP }; @@ -78,13 +79,15 @@ namespace datatype { class constructor { symbol m_name; + symbol m_recognizer; ptr_vector m_accessors; def* m_def; public: - constructor(symbol n): m_name(n) {} + constructor(symbol n, symbol const& r): m_name(n), m_recognizer(r) {} ~constructor(); void add(accessor* a) { m_accessors.push_back(a); a->attach(this); } symbol const& name() const { return m_name; } + symbol const& recognizer() const { return m_recognizer; } ptr_vector const& accessors() const { return m_accessors; } ptr_vector::const_iterator begin() const { return m_accessors.begin(); } ptr_vector::const_iterator end() const { return m_accessors.end(); } @@ -290,6 +293,10 @@ namespace datatype { unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); + func_decl * mk_is( + unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + symbol datatype_name(sort * s) const { //SASSERT(u().is_datatype(s)); return s->get_parameter(0).get_symbol(); @@ -340,11 +347,15 @@ namespace datatype { bool is_enum_sort(sort* s); bool is_recursive(sort * ty); bool is_constructor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_CONSTRUCTOR); } - bool is_recognizer(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_RECOGNISER); } + bool is_recognizer(func_decl * f) const { return is_recognizer0(f) || is_is(f); } + bool is_recognizer0(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_RECOGNISER); } + bool is_is(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_IS); } bool is_accessor(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_ACCESSOR); } bool is_update_field(func_decl * f) const { return is_decl_of(f, m_family_id, OP_DT_UPDATE_FIELD); } bool is_constructor(app * f) const { return is_app_of(f, m_family_id, OP_DT_CONSTRUCTOR); } - bool is_recognizer(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER); } + bool is_recognizer0(app * f) const { return is_app_of(f, m_family_id, OP_DT_RECOGNISER);} + bool is_is(app * f) const { return is_app_of(f, m_family_id, OP_DT_IS);} + bool is_recognizer(app * f) const { return is_recognizer0(f) || is_is(f); } bool is_accessor(app * f) const { return is_app_of(f, m_family_id, OP_DT_ACCESSOR); } bool is_update_field(app * f) const { return is_app_of(f, m_family_id, OP_DT_UPDATE_FIELD); } ptr_vector const * get_datatype_constructors(sort * ty); @@ -401,7 +412,7 @@ inline accessor_decl * mk_accessor_decl(ast_manager& m, symbol const & n, type_r } inline constructor_decl * mk_constructor_decl(symbol const & n, symbol const & r, unsigned num_accessors, accessor_decl * * acs) { - constructor_decl* c = alloc(constructor_decl, n); + constructor_decl* c = alloc(constructor_decl, n, r); for (unsigned i = 0; i < num_accessors; ++i) { c->add(acs[i]); } diff --git a/src/ast/rewriter/datatype_rewriter.cpp b/src/ast/rewriter/datatype_rewriter.cpp index 9efa61f70..f0a95929b 100644 --- a/src/ast/rewriter/datatype_rewriter.cpp +++ b/src/ast/rewriter/datatype_rewriter.cpp @@ -23,6 +23,7 @@ br_status datatype_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr switch(f->get_decl_kind()) { case OP_DT_CONSTRUCTOR: return BR_FAILED; case OP_DT_RECOGNISER: + case OP_DT_IS: // // simplify is_cons(cons(x,y)) -> true // simplify is_cons(nil) -> false diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index b52440393..39c4a1078 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -753,18 +753,14 @@ br_status poly_rewriter::cancel_monomials(expr * lhs, expr * rhs, bool m normalize(c); - TRACE("mk_le_bug", tout << c << "\n";); - if (!has_multiple && num_coeffs <= 1) { if (move) { if (is_numeral(rhs)) { - TRACE("mk_le_bug", tout << "rhs is numeral\n";); return BR_FAILED; } } else { if (num_coeffs == 0 || is_numeral(rhs)) { - TRACE("mk_le_bug", tout << "rhs is numeral or no coeffs\n";); return BR_FAILED; } } diff --git a/src/ast/static_features.cpp b/src/ast/static_features.cpp index 3c8333d02..3db4d02a2 100644 --- a/src/ast/static_features.cpp +++ b/src/ast/static_features.cpp @@ -145,18 +145,19 @@ bool static_features::is_diff_atom(expr const * e) const { return true; if (!is_numeral(rhs)) return false; - // lhs can be 'x' or '(+ x (* -1 y))' + // lhs can be 'x' or '(+ x (* -1 y))' or '(+ (* -1 x) y)' if (!is_arith_expr(lhs)) return true; expr* arg1, *arg2; if (!m_autil.is_add(lhs, arg1, arg2)) return false; - // x - if (is_arith_expr(arg1)) - return false; - // arg2: (* -1 y) expr* m1, *m2; - return m_autil.is_mul(arg2, m1, m2) && is_minus_one(m1) && !is_arith_expr(m2); + if (!is_arith_expr(arg1) && m_autil.is_mul(arg2, m1, m2) && is_minus_one(m1) && !is_arith_expr(m2)) + return true; + if (!is_arith_expr(arg2) && m_autil.is_mul(arg1, m1, m2) && is_minus_one(m1) && !is_arith_expr(m2)) + return true; + return false; + } bool static_features::is_gate(expr const * e) const { diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index c81170ba4..21b66febd 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -15,21 +15,21 @@ Author: Notes: --*/ -#include "cmd_context/cmd_context.h" +#include "util/gparams.h" +#include "util/env_params.h" #include "util/version.h" #include "ast/ast_smt_pp.h" #include "ast/ast_smt2_pp.h" #include "ast/ast_pp.h" -#include "model/model_smt2_pp.h" #include "ast/array_decl_plugin.h" #include "ast/pp.h" +#include "ast/well_sorted.h" +#include "ast/pp_params.hpp" +#include "model/model_smt2_pp.h" +#include "cmd_context/cmd_context.h" #include "cmd_context/cmd_util.h" #include "cmd_context/simplify_cmd.h" #include "cmd_context/eval_cmd.h" -#include "util/gparams.h" -#include "util/env_params.h" -#include "ast/well_sorted.h" -#include "ast/pp_params.hpp" class help_cmd : public cmd { svector m_cmds; @@ -79,19 +79,15 @@ public: } // named_cmd_lt is not a total order for commands, but this is irrelevant for Linux x Windows behavior std::sort(cmds.begin(), cmds.end(), named_cmd_lt()); - vector::const_iterator it2 = cmds.begin(); - vector::const_iterator end2 = cmds.end(); - for (; it2 != end2; ++it2) { - display_cmd(ctx, it2->first, it2->second); + for (named_cmd const& nc : cmds) { + display_cmd(ctx, nc.first, nc.second); } } else { - svector::const_iterator it = m_cmds.begin(); - svector::const_iterator end = m_cmds.end(); - for (; it != end; ++it) { - cmd * c = ctx.find_cmd(*it); + for (symbol const& s : m_cmds) { + cmd * c = ctx.find_cmd(s); SASSERT(c); - display_cmd(ctx, *it, c); + display_cmd(ctx, s, c); } } ctx.regular_stream() << "\"\n"; @@ -136,11 +132,10 @@ ATOMIC_CMD(get_assignment_cmd, "get-assignment", "retrieve assignment", { ctx.get_check_sat_result()->get_model(m); ctx.regular_stream() << "("; dictionary const & macros = ctx.get_macros(); - dictionary::iterator it = macros.begin(); - dictionary::iterator end = macros.end(); - for (bool first = true; it != end; ++it) { - symbol const & name = (*it).m_key; - macro_decls const & _m = (*it).m_value; + bool first = true; + for (auto const& kv : macros) { + symbol const & name = kv.m_key; + macro_decls const & _m = kv.m_value; for (auto md : _m) { if (md.m_domain.size() == 0 && ctx.m().is_bool(md.m_body)) { expr_ref val(ctx.m()); @@ -211,14 +206,13 @@ static void print_core(cmd_context& ctx) { ptr_vector core; ctx.get_check_sat_result()->get_unsat_core(core); ctx.regular_stream() << "("; - ptr_vector::const_iterator it = core.begin(); - ptr_vector::const_iterator end = core.end(); - for (bool first = true; it != end; ++it) { + bool first = true; + for (expr* e : core) { if (first) first = false; else ctx.regular_stream() << " "; - ctx.regular_stream() << mk_ismt2_pp(*it, ctx.m()); + ctx.regular_stream() << mk_ismt2_pp(e, ctx.m()); } ctx.regular_stream() << ")" << std::endl; } diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index e93e51186..c0e1c9f9c 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -18,7 +18,10 @@ Notes: #include #include "util/tptr.h" -#include "cmd_context/cmd_context.h" +#include "util/cancel_eh.h" +#include "util/scoped_ctrl_c.h" +#include "util/dec_ref_util.h" +#include "util/scoped_timer.h" #include "ast/func_decl_dependencies.h" #include "ast/arith_decl_plugin.h" #include "ast/bv_decl_plugin.h" @@ -31,22 +34,19 @@ Notes: #include "ast/rewriter/var_subst.h" #include "ast/pp.h" #include "ast/ast_smt2_pp.h" -#include "cmd_context/basic_cmds.h" -#include "util/cancel_eh.h" -#include "util/scoped_ctrl_c.h" -#include "util/dec_ref_util.h" #include "ast/decl_collector.h" #include "ast/well_sorted.h" -#include "model/model_evaluator.h" #include "ast/for_each_expr.h" -#include "util/scoped_timer.h" -#include "cmd_context/interpolant_cmds.h" +#include "ast/rewriter/th_rewriter.h" +#include "model/model_evaluator.h" #include "model/model_smt2_pp.h" #include "model/model_v2_pp.h" #include "model/model_params.hpp" -#include "ast/rewriter/th_rewriter.h" #include "tactic/tactic_exception.h" #include "solver/smt_logics.h" +#include "cmd_context/basic_cmds.h" +#include "cmd_context/interpolant_cmds.h" +#include "cmd_context/cmd_context.h" func_decls::func_decls(ast_manager & m, func_decl * f): m_decls(TAG(func_decl*, f, 0)) { @@ -61,11 +61,9 @@ void func_decls::finalize(ast_manager & m) { else { TRACE("func_decls", tout << "finalize...\n";); func_decl_set * fs = UNTAG(func_decl_set *, m_decls); - func_decl_set::iterator it = fs->begin(); - func_decl_set::iterator end = fs->end(); - for (; it != end; ++it) { - TRACE("func_decls", tout << "dec_ref of " << (*it)->get_name() << " ref_count: " << (*it)->get_ref_count() << "\n";); - m.dec_ref(*it); + for (func_decl * f : *fs) { + TRACE("func_decls", tout << "dec_ref of " << f->get_name() << " ref_count: " << f->get_ref_count() << "\n";); + m.dec_ref(f); } dealloc(fs); } @@ -161,10 +159,7 @@ bool func_decls::clash(func_decl * f) const { if (GET_TAG(m_decls) == 0) return false; func_decl_set * fs = UNTAG(func_decl_set *, m_decls); - func_decl_set::iterator it = fs->begin(); - func_decl_set::iterator end = fs->end(); - for (; it != end; ++it) { - func_decl * g = *it; + for (func_decl * g : *fs) { if (g == f) continue; if (g->get_arity() != f->get_arity()) @@ -201,10 +196,7 @@ func_decl * func_decls::find(unsigned arity, sort * const * domain, sort * range if (!more_than_one()) return first(); func_decl_set * fs = UNTAG(func_decl_set *, m_decls); - func_decl_set::iterator it = fs->begin(); - func_decl_set::iterator end = fs->end(); - for (; it != end; it++) { - func_decl * f = *it; + for (func_decl * f : *fs) { if (range != 0 && f->get_range() != range) continue; if (f->get_arity() != arity) @@ -1957,11 +1949,9 @@ void cmd_context::dt_eh::operator()(sort * dt, pdecl* pd) { 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";); -#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); diff --git a/src/cmd_context/pdecl.cpp b/src/cmd_context/pdecl.cpp index 4417061ec..9d6c5065e 100644 --- a/src/cmd_context/pdecl.cpp +++ b/src/cmd_context/pdecl.cpp @@ -267,8 +267,8 @@ public: psort_decl::psort_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n): pdecl(id, num_params), - m_psort_kind(PSORT_BASE), m_name(n), + m_psort_kind(PSORT_BASE), m_inst_cache(0) { } diff --git a/src/cmd_context/tactic_cmds.cpp b/src/cmd_context/tactic_cmds.cpp index b5ad0707d..3eafc6bbd 100644 --- a/src/cmd_context/tactic_cmds.cpp +++ b/src/cmd_context/tactic_cmds.cpp @@ -255,11 +255,9 @@ public: result->m_core.append(core_elems.size(), core_elems.c_ptr()); if (p.get_bool("print_unsat_core", false)) { ctx.regular_stream() << "(unsat-core"; - ptr_vector::const_iterator it = core_elems.begin(); - ptr_vector::const_iterator end = core_elems.end(); - for (; it != end; ++it) { + for (expr * e : core_elems) { ctx.regular_stream() << " "; - ctx.display(ctx.regular_stream(), *it); + ctx.display(ctx.regular_stream(), e); } ctx.regular_stream() << ")" << std::endl; } diff --git a/src/smt/theory_dense_diff_logic_def.h b/src/smt/theory_dense_diff_logic_def.h index 342766c04..ad7727a89 100644 --- a/src/smt/theory_dense_diff_logic_def.h +++ b/src/smt/theory_dense_diff_logic_def.h @@ -127,7 +127,7 @@ namespace smt { if (!m_non_diff_logic_exprs) { TRACE("non_diff_logic", tout << "found non diff logic expression:\n" << mk_pp(n, get_manager()) << "\n";); get_context().push_trail(value_trail(m_non_diff_logic_exprs)); - IF_VERBOSE(0, verbose_stream() << "(smt.diff_logic: non-diff logic expression " << mk_pp(n, get_manager()) << ")\n";); + IF_VERBOSE(0, verbose_stream() << "(smt.diff_logic: non-diff logic expression " << mk_pp(n, get_manager()) << ")\n";); m_non_diff_logic_exprs = true; } } @@ -154,6 +154,9 @@ namespace smt { if (m_autil.is_add(lhs) && to_app(lhs)->get_num_args() == 2 && is_times_minus_one(to_app(lhs)->get_arg(1), s)) { t = to_app(to_app(lhs)->get_arg(0)); } + else if (m_autil.is_add(lhs) && to_app(lhs)->get_num_args() == 2 && is_times_minus_one(to_app(lhs)->get_arg(0), s)) { + t = to_app(to_app(lhs)->get_arg(1)); + } else if (m_autil.is_mul(lhs) && to_app(lhs)->get_num_args() == 2 && m_autil.is_minus_one(to_app(lhs)->get_arg(0))) { s = to_app(to_app(lhs)->get_arg(1)); t = mk_zero_for(s); diff --git a/src/test/get_consequences.cpp b/src/test/get_consequences.cpp index 229cbe834..b9a54245e 100644 --- a/src/test/get_consequences.cpp +++ b/src/test/get_consequences.cpp @@ -65,12 +65,12 @@ void test2() { constructor_decl* G = mk_constructor_decl(symbol("G"), symbol("is-G"), 0, 0); constructor_decl* B = mk_constructor_decl(symbol("B"), symbol("is-B"), 0, 0); constructor_decl* constrs[3] = { R, G, B }; - datatype_decl * enum_sort = mk_datatype_decl(dtutil, symbol("RGB"), 3, constrs); + datatype_decl * enum_sort = mk_datatype_decl(dtutil, symbol("RGB"), 0, nullptr, 3, constrs); VERIFY(dt.mk_datatypes(1, &enum_sort, 0, 0, new_sorts)); sort* rgb = new_sorts[0].get(); expr_ref x = mk_const(m, "x", rgb), y = mk_const(m, "y", rgb), z = mk_const(m, "z", rgb); - ptr_vector const& enums = dtutil.get_datatype_constructors(rgb); + ptr_vector const& enums = *dtutil.get_datatype_constructors(rgb); expr_ref r = expr_ref(m.mk_const(enums[0]), m); expr_ref g = expr_ref(m.mk_const(enums[1]), m); expr_ref b = expr_ref(m.mk_const(enums[2]), m);