mirror of
https://github.com/Z3Prover/z3
synced 2025-08-28 05:58:55 +00:00
Cleanup fixedpoint options
Replace pdr options with spacer Repace fixedpoint module with fp
This commit is contained in:
parent
619f681d28
commit
9109968e55
23 changed files with 344 additions and 353 deletions
|
@ -20,7 +20,7 @@ Revision History:
|
|||
#include "ast/expr_abstract.h"
|
||||
#include "muz/base/dl_context.h"
|
||||
#include "muz/base/dl_context.h"
|
||||
#include "muz/base/fixedpoint_params.hpp"
|
||||
#include "muz/base/fp_params.hpp"
|
||||
#include "muz/transforms/dl_mk_array_eq_rewrite.h"
|
||||
#include "ast/factor_equivs.h"
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Revision History:
|
|||
#include "muz/base/dl_context.h"
|
||||
#include "ast/rewriter/expr_safe_replace.h"
|
||||
#include "ast/expr_abstract.h"
|
||||
#include "muz/base/fixedpoint_params.hpp"
|
||||
#include "muz/base/fp_params.hpp"
|
||||
|
||||
namespace datalog {
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ Revision History:
|
|||
#include "ast/rewriter/expr_safe_replace.h"
|
||||
#include "tactic/generic_model_converter.h"
|
||||
#include "muz/transforms/dl_mk_interp_tail_simplifier.h"
|
||||
#include "muz/base/fixedpoint_params.hpp"
|
||||
#include "muz/base/fp_params.hpp"
|
||||
#include "ast/scoped_proof.h"
|
||||
#include "model/model_v2_pp.h"
|
||||
|
||||
|
@ -32,9 +32,9 @@ namespace datalog {
|
|||
|
||||
//
|
||||
// P(v) :- Q(extract[1:1]v ++ 0), R(1 ++ extract[0:0]v).
|
||||
// ->
|
||||
// ->
|
||||
// P(bv(x,y)) :- Q(bv(x,0)), R(bv(1,y)) .
|
||||
//
|
||||
//
|
||||
// Introduce P_bv:
|
||||
// P_bv(x,y) :- Q_bv(x,0), R_bv(1,y)
|
||||
// P(bv(x,y)) :- P_bv(x,y)
|
||||
|
@ -51,7 +51,7 @@ namespace datalog {
|
|||
bit_blast_model_converter(ast_manager& m):
|
||||
m(m),
|
||||
m_bv(m),
|
||||
m_old_funcs(m),
|
||||
m_old_funcs(m),
|
||||
m_new_funcs(m) {}
|
||||
|
||||
void insert(func_decl* old_f, func_decl* new_f) {
|
||||
|
@ -73,7 +73,7 @@ namespace datalog {
|
|||
func_decl* q = m_old_funcs[i].get();
|
||||
func_interp* f = model->get_func_interp(p);
|
||||
if (!f) continue;
|
||||
expr_ref body(m);
|
||||
expr_ref body(m);
|
||||
unsigned arity_q = q->get_arity();
|
||||
TRACE("dl",
|
||||
model_v2_pp(tout, *model);
|
||||
|
@ -87,10 +87,10 @@ namespace datalog {
|
|||
if (f) {
|
||||
body = f->get_interp();
|
||||
SASSERT(!f->is_partial());
|
||||
SASSERT(body);
|
||||
SASSERT(body);
|
||||
}
|
||||
else {
|
||||
body = m.mk_false();
|
||||
body = m.mk_false();
|
||||
}
|
||||
unsigned idx = 0;
|
||||
expr_ref arg(m), proj(m);
|
||||
|
@ -104,18 +104,18 @@ namespace datalog {
|
|||
for (unsigned k = 0; k < sz; ++k) {
|
||||
parameter p(k);
|
||||
proj = m.mk_app(m_bv.get_family_id(), OP_BIT2BOOL, 1, &p, 1, &t);
|
||||
sub.insert(m.mk_var(idx++, m.mk_bool_sort()), proj);
|
||||
sub.insert(m.mk_var(idx++, m.mk_bool_sort()), proj);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sub.insert(m.mk_var(idx++, s), arg);
|
||||
}
|
||||
}
|
||||
sub(body);
|
||||
sub(body);
|
||||
g->set_else(body);
|
||||
model->register_decl(q, g);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class expand_mkbv_cfg : public default_rewriter_cfg {
|
||||
|
@ -134,10 +134,10 @@ namespace datalog {
|
|||
public:
|
||||
|
||||
expand_mkbv_cfg(context& ctx):
|
||||
m_context(ctx),
|
||||
m_context(ctx),
|
||||
m(ctx.get_manager()),
|
||||
m_util(m),
|
||||
m_args(m),
|
||||
m_args(m),
|
||||
m_f_vars(m),
|
||||
m_g_vars(m),
|
||||
m_old_funcs(m),
|
||||
|
@ -152,8 +152,8 @@ namespace datalog {
|
|||
void set_dst(rule_set* dst) { m_dst = dst; }
|
||||
func_decl_ref_vector const& old_funcs() const { return m_old_funcs; }
|
||||
func_decl_ref_vector const& new_funcs() const { return m_new_funcs; }
|
||||
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
|
||||
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
|
||||
if (num == 0) {
|
||||
if (m_src->is_output_predicate(f))
|
||||
m_dst->set_output_predicate(f);
|
||||
|
@ -165,9 +165,9 @@ namespace datalog {
|
|||
return BR_FAILED;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// f(mk_bv(args),...)
|
||||
//
|
||||
//
|
||||
m_args.reset();
|
||||
m_g_vars.reset();
|
||||
m_f_vars.reset();
|
||||
|
@ -191,9 +191,9 @@ namespace datalog {
|
|||
}
|
||||
}
|
||||
func_decl* g = nullptr;
|
||||
|
||||
|
||||
if (!m_pred2blast.find(f, g)) {
|
||||
|
||||
|
||||
ptr_vector<sort> domain;
|
||||
for (unsigned i = 0; i < m_args.size(); ++i) {
|
||||
domain.push_back(m.get_sort(m_args[i].get()));
|
||||
|
@ -262,7 +262,7 @@ namespace datalog {
|
|||
m_params.set_bool("blast_quant", true);
|
||||
m_blaster.updt_params(m_params);
|
||||
}
|
||||
|
||||
|
||||
rule_set * operator()(rule_set const & source) {
|
||||
// TODO pc
|
||||
if (!m_context.xform_bit_blast()) {
|
||||
|
@ -270,8 +270,8 @@ namespace datalog {
|
|||
}
|
||||
rule_manager& rm = m_context.get_rule_manager();
|
||||
unsigned sz = source.get_num_rules();
|
||||
expr_ref fml(m);
|
||||
rule_set * result = alloc(rule_set, m_context);
|
||||
expr_ref fml(m);
|
||||
rule_set * result = alloc(rule_set, m_context);
|
||||
m_rewriter.m_cfg.set_src(&source);
|
||||
m_rewriter.m_cfg.set_dst(result);
|
||||
for (unsigned i = 0; !m_context.canceled() && i < sz; ++i) {
|
||||
|
@ -299,8 +299,8 @@ namespace datalog {
|
|||
if (!source.contains(*I))
|
||||
result->set_output_predicate(*I);
|
||||
}
|
||||
|
||||
if (m_context.get_model_converter()) {
|
||||
|
||||
if (m_context.get_model_converter()) {
|
||||
generic_model_converter* fmc = alloc(generic_model_converter, m, "dl_mk_bit_blast");
|
||||
bit_blast_model_converter* bvmc = alloc(bit_blast_model_converter, m);
|
||||
func_decl_ref_vector const& old_funcs = m_rewriter.m_cfg.old_funcs();
|
||||
|
@ -311,7 +311,7 @@ namespace datalog {
|
|||
}
|
||||
m_context.add_model_converter(concat(bvmc, fmc));
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
@ -326,6 +326,6 @@ namespace datalog {
|
|||
|
||||
rule_set * mk_bit_blast::operator()(rule_set const & source) {
|
||||
return (*m_impl)(source);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@ Revision History:
|
|||
#include "muz/transforms/dl_mk_interp_tail_simplifier.h"
|
||||
#include "ast/ast_util.h"
|
||||
|
||||
#include "muz/base/fixedpoint_params.hpp"
|
||||
#include "muz/base/fp_params.hpp"
|
||||
namespace datalog {
|
||||
|
||||
// -----------------------------------
|
||||
|
@ -46,7 +46,7 @@ namespace datalog {
|
|||
bool mk_interp_tail_simplifier::rule_substitution::unify(expr * e1, expr * e2) {
|
||||
SASSERT(m_rule);
|
||||
|
||||
//we need to apply the current substitution in order to ensure the unifier
|
||||
//we need to apply the current substitution in order to ensure the unifier
|
||||
//works in an incremental way
|
||||
expr_ref e1_s(m);
|
||||
expr_ref e2_s(m);
|
||||
|
@ -268,7 +268,7 @@ namespace datalog {
|
|||
if (neq) {
|
||||
have_pair = false;
|
||||
v[prev_pair_idx] = neq;
|
||||
|
||||
|
||||
read_idx++;
|
||||
continue;
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ namespace datalog {
|
|||
|
||||
//bool detect_same_variable_conj_pairs
|
||||
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result,
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result,
|
||||
proof_ref & result_pr)
|
||||
{
|
||||
if (m.is_not(f) && (m.is_and(args[0]) || m.is_or(args[0]))) {
|
||||
|
@ -307,15 +307,15 @@ namespace datalog {
|
|||
m_app_args.push_back(tmp);
|
||||
}
|
||||
if (m.is_and(args[0])) {
|
||||
result = mk_or(m_app_args);
|
||||
result = mk_or(m_app_args);
|
||||
}
|
||||
else {
|
||||
result = mk_and(m_app_args);
|
||||
result = mk_and(m_app_args);
|
||||
}
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
if (!m.is_and(f) && !m.is_or(f)) {
|
||||
return BR_FAILED;
|
||||
if (!m.is_and(f) && !m.is_or(f)) {
|
||||
return BR_FAILED;
|
||||
}
|
||||
if (num == 0) {
|
||||
if (m.is_and(f)) {
|
||||
|
@ -375,7 +375,7 @@ namespace datalog {
|
|||
m_simp(ctx.get_rewriter()),
|
||||
a(m),
|
||||
m_rule_subst(ctx),
|
||||
m_tail(m),
|
||||
m_tail(m),
|
||||
m_itail_members(m),
|
||||
m_conj(m) {
|
||||
m_cfg = alloc(normalizer_cfg, m);
|
||||
|
@ -386,7 +386,7 @@ namespace datalog {
|
|||
dealloc(m_rw);
|
||||
dealloc(m_cfg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mk_interp_tail_simplifier::simplify_expr(app * a, expr_ref& res)
|
||||
{
|
||||
|
@ -537,7 +537,7 @@ namespace datalog {
|
|||
simplify_expr(itail.get(), simp_res);
|
||||
|
||||
modified |= itail.get() != simp_res.get();
|
||||
|
||||
|
||||
if (m.is_false(simp_res)) {
|
||||
TRACE("dl", r->display(m_context, tout << "rule is infeasible\n"););
|
||||
return false;
|
||||
|
@ -568,7 +568,7 @@ namespace datalog {
|
|||
|
||||
rule_ref pro_var_eq_result(m_context.get_rule_manager());
|
||||
if (propagate_variable_equivalences(res, pro_var_eq_result)) {
|
||||
SASSERT(rule_counter().get_max_rule_var(*r.get())==0 ||
|
||||
SASSERT(rule_counter().get_max_rule_var(*r.get())==0 ||
|
||||
rule_counter().get_max_rule_var(*r.get()) > rule_counter().get_max_rule_var(*pro_var_eq_result.get()));
|
||||
r = pro_var_eq_result;
|
||||
goto start;
|
||||
|
@ -607,8 +607,8 @@ namespace datalog {
|
|||
rule_set * res = alloc(rule_set, m_context);
|
||||
if (transform_rules(source, *res)) {
|
||||
res->inherit_predicates(source);
|
||||
TRACE("dl",
|
||||
source.display(tout);
|
||||
TRACE("dl",
|
||||
source.display(tout);
|
||||
res->display(tout););
|
||||
} else {
|
||||
dealloc(res);
|
||||
|
@ -616,6 +616,5 @@ namespace datalog {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ Abstract:
|
|||
|
||||
Author:
|
||||
|
||||
Ken McMillan
|
||||
Ken McMillan
|
||||
Andrey Rybalchenko
|
||||
Nikolaj Bjorner (nbjorner) 2013-04-02
|
||||
|
||||
|
@ -23,13 +23,12 @@ Revision History:
|
|||
#include "muz/base/dl_context.h"
|
||||
#include "ast/rewriter/expr_safe_replace.h"
|
||||
#include "ast/expr_abstract.h"
|
||||
#include "muz/base/fixedpoint_params.hpp"
|
||||
|
||||
|
||||
namespace datalog {
|
||||
|
||||
|
||||
// model converter:
|
||||
// model converter:
|
||||
// Given model for P^(x, y, i, a[i])
|
||||
// create model: P(x,y,a) == forall i . P^(x,y,i,a[i])
|
||||
// requires substitution and list of bound variables.
|
||||
|
@ -55,7 +54,7 @@ namespace datalog {
|
|||
|
||||
void display(std::ostream& out) override { display_add(out, m); }
|
||||
|
||||
void get_units(obj_map<expr, bool>& units) override { units.reset(); }
|
||||
void get_units(obj_map<expr, bool>& units) override { units.reset(); }
|
||||
|
||||
void insert(func_decl* old_p, func_decl* new_p, expr_ref_vector& sub, sort_ref_vector& sorts, svector<bool> const& bound) {
|
||||
m_old_funcs.push_back(old_p);
|
||||
|
@ -74,7 +73,7 @@ namespace datalog {
|
|||
sort_ref_vector const& sorts = m_sorts[i];
|
||||
svector<bool> const& is_bound = m_bound[i];
|
||||
func_interp* f = old_model->get_func_interp(p);
|
||||
expr_ref body(m);
|
||||
expr_ref body(m);
|
||||
unsigned arity_q = q->get_arity();
|
||||
SASSERT(0 < p->get_arity());
|
||||
func_interp* g = alloc(func_interp, m, arity_q);
|
||||
|
@ -82,7 +81,7 @@ namespace datalog {
|
|||
if (f) {
|
||||
body = f->get_interp();
|
||||
SASSERT(!f->is_partial());
|
||||
SASSERT(body);
|
||||
SASSERT(body);
|
||||
}
|
||||
else {
|
||||
expr_ref_vector args(m);
|
||||
|
@ -94,7 +93,7 @@ namespace datalog {
|
|||
// Create quantifier wrapper around body.
|
||||
|
||||
TRACE("dl", tout << mk_pp(body, m) << "\n";);
|
||||
// 1. replace variables by the compound terms from
|
||||
// 1. replace variables by the compound terms from
|
||||
// the original predicate.
|
||||
expr_safe_replace rep(m);
|
||||
for (unsigned i = 0; i < sub.size(); ++i) {
|
||||
|
@ -121,7 +120,7 @@ namespace datalog {
|
|||
_free.push_back(consts.back());
|
||||
}
|
||||
}
|
||||
rep(body);
|
||||
rep(body);
|
||||
rep.reset();
|
||||
|
||||
TRACE("dl", tout << mk_pp(body, m) << "\n";);
|
||||
|
@ -130,18 +129,18 @@ namespace datalog {
|
|||
body = m.mk_forall(names.size(), bound_sorts.c_ptr(), names.c_ptr(), body);
|
||||
|
||||
TRACE("dl", tout << mk_pp(body, m) << "\n";);
|
||||
// 4. replace remaining constants by variables.
|
||||
// 4. replace remaining constants by variables.
|
||||
for (unsigned i = 0; i < _free.size(); ++i) {
|
||||
rep.insert(_free[i].get(), m.mk_var(i, m.get_sort(_free[i].get())));
|
||||
}
|
||||
rep(body);
|
||||
rep(body);
|
||||
g->set_else(body);
|
||||
TRACE("dl", tout << mk_pp(body, m) << "\n";);
|
||||
|
||||
new_model->register_decl(q, g);
|
||||
}
|
||||
}
|
||||
old_model = new_model;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mk_quantifier_abstraction::mk_quantifier_abstraction(
|
||||
|
@ -154,7 +153,7 @@ namespace datalog {
|
|||
m_mc(nullptr) {
|
||||
}
|
||||
|
||||
mk_quantifier_abstraction::~mk_quantifier_abstraction() {
|
||||
mk_quantifier_abstraction::~mk_quantifier_abstraction() {
|
||||
}
|
||||
|
||||
func_decl* mk_quantifier_abstraction::declare_pred(rule_set const& rules, rule_set& dst, func_decl* old_p) {
|
||||
|
@ -178,7 +177,7 @@ namespace datalog {
|
|||
func_decl* new_p = nullptr;
|
||||
if (!m_old2new.find(old_p, new_p)) {
|
||||
expr_ref_vector sub(m), vars(m);
|
||||
svector<bool> bound;
|
||||
svector<bool> bound;
|
||||
sort_ref_vector domain(m), sorts(m);
|
||||
expr_ref arg(m);
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
|
@ -208,7 +207,7 @@ namespace datalog {
|
|||
bound.push_back(false);
|
||||
sub.push_back(arg);
|
||||
sorts.push_back(s0);
|
||||
}
|
||||
}
|
||||
SASSERT(old_p->get_range() == m.mk_bool_sort());
|
||||
new_p = m.mk_func_decl(old_p->get_name(), domain.size(), domain.c_ptr(), old_p->get_range());
|
||||
m_refs.push_back(new_p);
|
||||
|
@ -242,12 +241,12 @@ namespace datalog {
|
|||
}
|
||||
args.push_back(arg);
|
||||
}
|
||||
TRACE("dl",
|
||||
TRACE("dl",
|
||||
tout << mk_pp(new_p, m) << "\n";
|
||||
for (unsigned i = 0; i < args.size(); ++i) {
|
||||
tout << mk_pp(args[i].get(), m) << "\n";
|
||||
});
|
||||
return app_ref(m.mk_app(new_p, args.size(), args.c_ptr()), m);
|
||||
return app_ref(m.mk_app(new_p, args.size(), args.c_ptr()), m);
|
||||
}
|
||||
|
||||
app_ref mk_quantifier_abstraction::mk_tail(rule_set const& rules, rule_set& dst, app* p) {
|
||||
|
@ -272,7 +271,7 @@ namespace datalog {
|
|||
for (unsigned i = 0; i < sz; ++i) {
|
||||
arg = ps->get_arg(i);
|
||||
sort* s = m.get_sort(arg);
|
||||
bool is_pattern = false;
|
||||
bool is_pattern = false;
|
||||
while (a.is_array(s)) {
|
||||
is_pattern = true;
|
||||
unsigned arity = get_array_arity(s);
|
||||
|
@ -304,9 +303,9 @@ namespace datalog {
|
|||
ptr_vector<expr> args2;
|
||||
args2.push_back(arg);
|
||||
args2.append(num_args, args);
|
||||
return a.mk_select(args2.size(), args2.c_ptr());
|
||||
return a.mk_select(args2.size(), args2.c_ptr());
|
||||
}
|
||||
|
||||
|
||||
rule_set * mk_quantifier_abstraction::operator()(rule_set const & source) {
|
||||
if (!m_ctx.quantify_arrays()) {
|
||||
return nullptr;
|
||||
|
@ -334,10 +333,10 @@ namespace datalog {
|
|||
}
|
||||
rule_set * result = alloc(rule_set, m_ctx);
|
||||
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
tail.reset();
|
||||
rule & r = *source.get_rule(i);
|
||||
TRACE("dl", r.display(m_ctx, tout); );
|
||||
TRACE("dl", r.display(m_ctx, tout); );
|
||||
unsigned cnt = vc.get_max_rule_var(r)+1;
|
||||
unsigned utsz = r.get_uninterpreted_tail_size();
|
||||
unsigned tsz = r.get_tail_size();
|
||||
|
@ -352,8 +351,8 @@ namespace datalog {
|
|||
proof_ref pr(m);
|
||||
rm.mk_rule(fml, pr, *result, r.name());
|
||||
TRACE("dl", result->last()->display(m_ctx, tout););
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// proof converter: proofs are not necessarily preserved using this transformation.
|
||||
|
||||
if (m_old2new.empty()) {
|
||||
|
@ -371,5 +370,3 @@ namespace datalog {
|
|||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ Revision History:
|
|||
Added linear_inline 2012-9-10 (nbjorner)
|
||||
|
||||
Disable inliner for quantified rules 2012-10-31 (nbjorner)
|
||||
|
||||
|
||||
Notes:
|
||||
|
||||
Resolution transformation (resolve):
|
||||
|
@ -27,7 +27,7 @@ Resolution transformation (resolve):
|
|||
--------------------------------------------------
|
||||
P(x) :- R(z), phi(x,y), psi(y,z)
|
||||
|
||||
Proof converter:
|
||||
Proof converter:
|
||||
|
||||
replace assumption (*) by rule and upper assumptions.
|
||||
|
||||
|
@ -37,9 +37,9 @@ Subsumption transformation (remove rule):
|
|||
P(x) :- Q(y), phi(x,y) Rules
|
||||
---------------------------------
|
||||
Rules
|
||||
|
||||
|
||||
Model converter:
|
||||
|
||||
|
||||
Model converter:
|
||||
|
||||
P(x) := P(x) or (exists y . Q(y) & phi(x,y))
|
||||
|
||||
|
@ -52,7 +52,7 @@ Subsumption transformation (remove rule):
|
|||
#include "ast/rewriter/rewriter.h"
|
||||
#include "ast/rewriter/rewriter_def.h"
|
||||
#include "muz/transforms/dl_mk_rule_inliner.h"
|
||||
#include "muz/base/fixedpoint_params.hpp"
|
||||
#include "muz/base/fp_params.hpp"
|
||||
|
||||
namespace datalog {
|
||||
|
||||
|
@ -67,15 +67,15 @@ namespace datalog {
|
|||
unsigned var_cnt = std::max(vc.get_max_rule_var(tgt), vc.get_max_rule_var(src))+1;
|
||||
m_subst.reset();
|
||||
m_subst.reserve(2, var_cnt);
|
||||
|
||||
|
||||
m_ready = m_unif(tgt.get_tail(tgt_idx), src.get_head(), m_subst);
|
||||
|
||||
if (m_ready) {
|
||||
m_deltas[0] = 0;
|
||||
m_deltas[1] = var_cnt;
|
||||
TRACE("dl",
|
||||
output_predicate(m_context, src.get_head(), tout << "unify rules ");
|
||||
output_predicate(m_context, tgt.get_head(), tout << "\n");
|
||||
TRACE("dl",
|
||||
output_predicate(m_context, src.get_head(), tout << "unify rules ");
|
||||
output_predicate(m_context, tgt.get_head(), tout << "\n");
|
||||
tout << "\n";);
|
||||
}
|
||||
return m_ready;
|
||||
|
@ -90,7 +90,7 @@ namespace datalog {
|
|||
}
|
||||
|
||||
void rule_unifier::apply(
|
||||
rule const& r, bool is_tgt, unsigned skipped_index,
|
||||
rule const& r, bool is_tgt, unsigned skipped_index,
|
||||
app_ref_vector& res, svector<bool>& res_neg) {
|
||||
unsigned rule_len = r.get_tail_size();
|
||||
for (unsigned i = 0; i < rule_len; i++) {
|
||||
|
@ -127,7 +127,7 @@ namespace datalog {
|
|||
);
|
||||
|
||||
if (m_normalize) {
|
||||
m_rm.fix_unbound_vars(res, true);
|
||||
m_rm.fix_unbound_vars(res, true);
|
||||
if (m_interp_simplifier.transform_rule(res.get(), simpl_rule)) {
|
||||
res = simpl_rule;
|
||||
return true;
|
||||
|
@ -150,8 +150,8 @@ namespace datalog {
|
|||
for (unsigned i = 0; i < sorts.size(); ++i) {
|
||||
v = m.mk_var(i, sorts[i]);
|
||||
m_subst.apply(2, m_deltas, expr_offset(v, is_tgt?0:1), w);
|
||||
result.push_back(w);
|
||||
}
|
||||
result.push_back(w);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ namespace datalog {
|
|||
expr_ref_vector s2 = m_unifier.get_rule_subst(src, false);
|
||||
datalog::resolve_rule(m_rm, tgt, src, tail_index, s1, s2, *res.get());
|
||||
}
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
TRACE("dl", res->display(m_context, tout << "interpreted tail is unsat\n"););
|
||||
|
@ -240,12 +240,12 @@ namespace datalog {
|
|||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// these conditions are optional, they avoid possible exponential increase
|
||||
//
|
||||
// these conditions are optional, they avoid possible exponential increase
|
||||
// in the size of the problem
|
||||
//
|
||||
//
|
||||
|
||||
return
|
||||
return
|
||||
//m_head_pred_non_empty_tails_ctr.get(pred)<=1
|
||||
m_head_pred_ctr.get(pred) <= 1
|
||||
|| (m_tail_pred_ctr.get(pred) <= 1 && m_head_pred_ctr.get(pred) <= 4)
|
||||
|
@ -253,7 +253,7 @@ namespace datalog {
|
|||
}
|
||||
|
||||
/** Caller has to dealloc the returned object */
|
||||
rule_set * mk_rule_inliner::create_allowed_rule_set(rule_set const & orig)
|
||||
rule_set * mk_rule_inliner::create_allowed_rule_set(rule_set const & orig)
|
||||
{
|
||||
rule_set * res = alloc(rule_set, m_context);
|
||||
for (rule * r : orig) {
|
||||
|
@ -268,7 +268,7 @@ namespace datalog {
|
|||
|
||||
/**
|
||||
Try to make the set of inlined predicates acyclic by forbidding inlining of one
|
||||
predicate from each strongly connected component. Return true if we did forbide some
|
||||
predicate from each strongly connected component. Return true if we did forbide some
|
||||
predicate, and false if the set of rules is already acyclic.
|
||||
*/
|
||||
bool mk_rule_inliner::forbid_preds_from_cycles(rule_set const & r)
|
||||
|
@ -276,7 +276,7 @@ namespace datalog {
|
|||
SASSERT(r.is_closed());
|
||||
|
||||
bool something_forbidden = false;
|
||||
|
||||
|
||||
const rule_stratifier::comp_vector& comps = r.get_stratifier().get_strats();
|
||||
|
||||
for (rule_stratifier::item_set * stratum : comps) {
|
||||
|
@ -293,12 +293,12 @@ namespace datalog {
|
|||
return something_forbidden;
|
||||
}
|
||||
|
||||
bool mk_rule_inliner::forbid_multiple_multipliers(const rule_set & orig,
|
||||
bool mk_rule_inliner::forbid_multiple_multipliers(const rule_set & orig,
|
||||
rule_set const & proposed_inlined_rules) {
|
||||
|
||||
bool something_forbidden = false;
|
||||
|
||||
const rule_stratifier::comp_vector& comps =
|
||||
const rule_stratifier::comp_vector& comps =
|
||||
proposed_inlined_rules.get_stratifier().get_strats();
|
||||
|
||||
for (rule_stratifier::item_set * stratum : comps) {
|
||||
|
@ -332,7 +332,7 @@ namespace datalog {
|
|||
}
|
||||
else {
|
||||
is_multi_head_pred = true;
|
||||
m_head_pred_ctr.get(head_pred) =
|
||||
m_head_pred_ctr.get(head_pred) =
|
||||
m_head_pred_ctr.get(head_pred)*tail_pred_head_cnt;
|
||||
}
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ namespace datalog {
|
|||
void mk_rule_inliner::plan_inlining(rule_set const & orig)
|
||||
{
|
||||
count_pred_occurrences(orig);
|
||||
|
||||
|
||||
scoped_ptr<rule_set> candidate_inlined_set = create_allowed_rule_set(orig);
|
||||
while (forbid_preds_from_cycles(*candidate_inlined_set)) {
|
||||
candidate_inlined_set = create_allowed_rule_set(orig);
|
||||
|
@ -458,8 +458,8 @@ namespace datalog {
|
|||
rule_ref r(rl, m_rm);
|
||||
func_decl * pred = r->get_decl();
|
||||
|
||||
// if inlining is allowed, then we are eliminating
|
||||
// this relation through inlining,
|
||||
// if inlining is allowed, then we are eliminating
|
||||
// this relation through inlining,
|
||||
// so we don't add its rules to the result
|
||||
|
||||
something_done |= !inlining_allowed(orig, pred) && transform_rule(orig, r, tgt);
|
||||
|
@ -472,14 +472,14 @@ namespace datalog {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return something_done;
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether rule r is oriented in a particular ordering.
|
||||
This is to avoid infinite cycle of inlining in the eager inliner.
|
||||
|
||||
|
||||
Out ordering is lexicographic, comparing atoms first on stratum they are in,
|
||||
then on arity and then on ast ID of their func_decl.
|
||||
*/
|
||||
|
@ -488,7 +488,7 @@ namespace datalog {
|
|||
unsigned head_strat = strat.get_predicate_strat(head_pred);
|
||||
unsigned head_arity = head_pred->get_arity();
|
||||
unsigned pt_len = r->get_positive_tail_size();
|
||||
for (unsigned ti=0; ti < pt_len; ++ti) {
|
||||
for (unsigned ti=0; ti < pt_len; ++ti) {
|
||||
func_decl * pred = r->get_decl(ti);
|
||||
unsigned pred_strat = strat.get_predicate_strat(pred);
|
||||
SASSERT(pred_strat <= head_strat);
|
||||
|
@ -516,7 +516,7 @@ namespace datalog {
|
|||
|
||||
unsigned pt_len = r->get_positive_tail_size();
|
||||
for (unsigned ti = 0; ti < pt_len; ++ti) {
|
||||
|
||||
|
||||
func_decl * pred = r->get_decl(ti);
|
||||
if (pred == head_pred || m_preds_with_facts.contains(pred)) { continue; }
|
||||
|
||||
|
@ -532,7 +532,7 @@ namespace datalog {
|
|||
}
|
||||
else {
|
||||
inlining_candidate = nullptr;
|
||||
|
||||
|
||||
for (unsigned ri = 0; ri < rule_cnt; ++ri) {
|
||||
rule * pred_rule = pred_rules[ri];
|
||||
if (!m_unifier.unify_rules(*r, ti, *pred_rule)) {
|
||||
|
@ -540,9 +540,9 @@ namespace datalog {
|
|||
continue;
|
||||
}
|
||||
if (inlining_candidate != nullptr) {
|
||||
// We have two rules that can be inlined into the current
|
||||
// We have two rules that can be inlined into the current
|
||||
// tail predicate. In this situation we don't do inlinning
|
||||
// on this tail atom, as we don't want the overall number
|
||||
// on this tail atom, as we don't want the overall number
|
||||
// of rules to increase.
|
||||
goto process_next_tail;
|
||||
}
|
||||
|
@ -608,14 +608,14 @@ namespace datalog {
|
|||
|
||||
P(1,x) :- P(1,z), phi(x,y), psi(y,z)
|
||||
|
||||
whenever P(0,x) is not unifiable with the
|
||||
whenever P(0,x) is not unifiable with the
|
||||
body of the rule where it appears (P(1,z))
|
||||
and P(0,x) is unifiable with at most one (?)
|
||||
and P(0,x) is unifiable with at most one (?)
|
||||
other rule (and it does not occur negatively).
|
||||
*/
|
||||
bool mk_rule_inliner::visitor::operator()(expr* e) {
|
||||
m_unifiers.append(m_positions.find(e));
|
||||
TRACE("dl",
|
||||
TRACE("dl",
|
||||
tout << "unifier: " << (m_unifiers.empty()?0:m_unifiers.back());
|
||||
tout << " num unifiers: " << m_unifiers.size();
|
||||
tout << " num positions: " << m_positions.find(e).size() << "\n";
|
||||
|
@ -640,7 +640,7 @@ namespace datalog {
|
|||
}
|
||||
|
||||
unsigned_vector const& mk_rule_inliner::visitor::del_position(expr* e, unsigned j) {
|
||||
obj_map<expr, unsigned_vector>::obj_map_entry * et = m_positions.find_core(e);
|
||||
obj_map<expr, unsigned_vector>::obj_map_entry * et = m_positions.find_core(e);
|
||||
SASSERT(et && et->get_data().m_value.contains(j));
|
||||
et->get_data().m_value.erase(j);
|
||||
return et->get_data().m_value;
|
||||
|
@ -654,7 +654,7 @@ namespace datalog {
|
|||
m_head_visitor.add_position(head, i);
|
||||
m_head_index.insert(head);
|
||||
m_pinned.push_back(r);
|
||||
|
||||
|
||||
if (source.is_output_predicate(headd) ||
|
||||
m_preds_with_facts.contains(headd)) {
|
||||
can_remove.set(i, false);
|
||||
|
@ -667,10 +667,10 @@ namespace datalog {
|
|||
m_tail_visitor.add_position(tail, i);
|
||||
m_tail_index.insert(tail);
|
||||
}
|
||||
bool can_exp =
|
||||
bool can_exp =
|
||||
tl_sz == 1
|
||||
&& r->get_positive_tail_size() == 1
|
||||
&& !m_preds_with_facts.contains(r->get_decl(0))
|
||||
&& r->get_positive_tail_size() == 1
|
||||
&& !m_preds_with_facts.contains(r->get_decl(0))
|
||||
&& !source.is_output_predicate(r->get_decl(0));
|
||||
can_expand.set(i, can_exp);
|
||||
}
|
||||
|
@ -682,14 +682,14 @@ namespace datalog {
|
|||
for (unsigned j = 0; j < tl_sz; ++j) {
|
||||
app* tail = r->get_tail(j);
|
||||
m_tail_visitor.del_position(tail, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define PRT(_x_) ((_x_)?"T":"F")
|
||||
|
||||
bool mk_rule_inliner::inline_linear(scoped_ptr<rule_set>& rules) {
|
||||
bool done_something = false;
|
||||
bool done_something = false;
|
||||
unsigned sz = rules->get_num_rules();
|
||||
|
||||
m_head_visitor.reset(sz);
|
||||
|
@ -704,7 +704,7 @@ namespace datalog {
|
|||
acc.push_back(rules->get_rule(i));
|
||||
}
|
||||
|
||||
// set up unification index.
|
||||
// set up unification index.
|
||||
svector<bool>& can_remove = m_head_visitor.can_remove();
|
||||
svector<bool>& can_expand = m_head_visitor.can_expand();
|
||||
|
||||
|
@ -729,7 +729,7 @@ namespace datalog {
|
|||
|
||||
svector<bool> valid;
|
||||
valid.reset();
|
||||
valid.resize(sz, true);
|
||||
valid.resize(sz, true);
|
||||
|
||||
bool allow_branching = m_context.get_params().xform_inline_linear_branch();
|
||||
|
||||
|
@ -738,9 +738,9 @@ namespace datalog {
|
|||
while (true) {
|
||||
|
||||
rule_ref r(acc[i].get(), m_rm);
|
||||
|
||||
|
||||
TRACE("dl", r->display(m_context, tout << "processing: " << i << "\n"););
|
||||
|
||||
|
||||
if (!valid.get(i)) {
|
||||
TRACE("dl", tout << "invalid: " << i << "\n";);
|
||||
break;
|
||||
|
@ -762,9 +762,9 @@ namespace datalog {
|
|||
TRACE("dl", tout << PRT(can_remove.get(j)) << " " << PRT(valid.get(j)) << " " << PRT(i != j) << "\n";);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
rule* r2 = acc[j].get();
|
||||
|
||||
|
||||
// check that the head of r2 only unifies with this single body position.
|
||||
TRACE("dl", output_predicate(m_context, r2->get_head(), tout << "unify head: "); tout << "\n";);
|
||||
m_tail_visitor.reset();
|
||||
|
@ -776,7 +776,7 @@ namespace datalog {
|
|||
TRACE("dl", tout << "too many tails " << num_tail_unifiers << "\n";);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
rule_ref rl_res(m_rm);
|
||||
if (!try_to_inline_rule(*r.get(), *r2, 0, rl_res)) {
|
||||
TRACE("dl", r->display(m_context, tout << "inlining failed\n"); r2->display(m_context, tout); );
|
||||
|
@ -787,12 +787,12 @@ namespace datalog {
|
|||
|
||||
del_rule(r, i);
|
||||
add_rule(*rules, rl_res.get(), i);
|
||||
|
||||
|
||||
|
||||
r = rl_res;
|
||||
acc[i] = r.get();
|
||||
can_expand.set(i, can_expand.get(j));
|
||||
|
||||
|
||||
if (num_tail_unifiers == 1) {
|
||||
TRACE("dl", tout << "setting invalid: " << j << "\n";);
|
||||
valid.set(j, false);
|
||||
|
@ -815,22 +815,22 @@ namespace datalog {
|
|||
res->inherit_predicates(*rules);
|
||||
TRACE("dl", res->display(tout););
|
||||
rules = res.detach();
|
||||
}
|
||||
}
|
||||
return done_something;
|
||||
}
|
||||
|
||||
rule_set * mk_rule_inliner::operator()(rule_set const & source) {
|
||||
|
||||
bool something_done = false;
|
||||
ref<horn_subsume_model_converter> hsmc;
|
||||
ref<horn_subsume_model_converter> hsmc;
|
||||
|
||||
if (source.get_num_rules() == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (rule const* r : source)
|
||||
if (has_quantifier(*r))
|
||||
return nullptr;
|
||||
for (rule const* r : source)
|
||||
if (has_quantifier(*r))
|
||||
return nullptr;
|
||||
|
||||
if (m_context.get_model_converter()) {
|
||||
hsmc = alloc(horn_subsume_model_converter, m);
|
||||
|
@ -841,15 +841,15 @@ namespace datalog {
|
|||
|
||||
if (m_context.get_params().xform_inline_eager()) {
|
||||
TRACE("dl", source.display(tout << "before eager inlining\n"););
|
||||
plan_inlining(source);
|
||||
something_done = transform_rules(source, *res);
|
||||
plan_inlining(source);
|
||||
something_done = transform_rules(source, *res);
|
||||
VERIFY(res->close()); //this transformation doesn't break the negation stratification
|
||||
// try eager inlining
|
||||
if (do_eager_inlining(res)) {
|
||||
something_done = true;
|
||||
}
|
||||
}
|
||||
TRACE("dl", res->display(tout << "after eager inlining\n"););
|
||||
}
|
||||
}
|
||||
if (something_done) {
|
||||
res->inherit_predicates(source);
|
||||
}
|
||||
|
@ -870,6 +870,5 @@ namespace datalog {
|
|||
|
||||
return res.detach();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ Revision History:
|
|||
|
||||
#include "muz/transforms/dl_mk_scale.h"
|
||||
#include "muz/base/dl_context.h"
|
||||
#include "muz/base/fixedpoint_params.hpp"
|
||||
#include "muz/base/fp_params.hpp"
|
||||
|
||||
namespace datalog {
|
||||
|
||||
|
@ -37,7 +37,7 @@ namespace datalog {
|
|||
m_trail.push_back(new_f);
|
||||
m_new2old.insert(new_f, old_f);
|
||||
}
|
||||
|
||||
|
||||
void get_units(obj_map<expr, bool>& units) override { units.reset(); }
|
||||
|
||||
void operator()(model_ref& md) override {
|
||||
|
@ -74,7 +74,7 @@ namespace datalog {
|
|||
old_model->register_decl(old_p, old_fi);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// register values that have not been scaled.
|
||||
unsigned sz = md->get_num_constants();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
|
@ -111,12 +111,12 @@ namespace datalog {
|
|||
m_ctx(ctx),
|
||||
a(m),
|
||||
m_trail(m),
|
||||
m_eqs(m) {
|
||||
m_eqs(m) {
|
||||
}
|
||||
|
||||
mk_scale::~mk_scale() {
|
||||
mk_scale::~mk_scale() {
|
||||
}
|
||||
|
||||
|
||||
rule_set * mk_scale::operator()(rule_set const & source) {
|
||||
if (!m_ctx.scale()) {
|
||||
return nullptr;
|
||||
|
@ -135,7 +135,7 @@ namespace datalog {
|
|||
}
|
||||
m_mc = smc.get();
|
||||
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
rule & r = *source.get_rule(i);
|
||||
unsigned utsz = r.get_uninterpreted_tail_size();
|
||||
unsigned tsz = r.get_tail_size();
|
||||
|
@ -157,10 +157,10 @@ namespace datalog {
|
|||
tail.push_back(a.mk_gt(m.mk_var(num_vars, a.mk_real()), a.mk_numeral(rational(0), false)));
|
||||
neg.resize(tail.size(), false);
|
||||
new_rule = rm.mk(new_pred, tail.size(), tail.c_ptr(), neg.c_ptr(), r.name(), true);
|
||||
result->add_rule(new_rule);
|
||||
result->add_rule(new_rule);
|
||||
if (source.is_output_predicate(r.get_decl())) {
|
||||
result->set_output_predicate(new_rule->get_decl());
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("dl", result->display(tout););
|
||||
if (m_mc) {
|
||||
|
@ -227,7 +227,7 @@ namespace datalog {
|
|||
a.is_lt(e) || a.is_gt(e)) {
|
||||
expr_ref_vector args(m);
|
||||
for (unsigned i = 0; i < ap->get_num_args(); ++i) {
|
||||
args.push_back(linearize(sigma_idx, ap->get_arg(i)));
|
||||
args.push_back(linearize(sigma_idx, ap->get_arg(i)));
|
||||
}
|
||||
result = m.mk_app(ap->get_decl(), args.size(), args.c_ptr());
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ Revision History:
|
|||
#include "ast/rewriter/rewriter.h"
|
||||
#include "ast/rewriter/rewriter_def.h"
|
||||
#include "muz/transforms/dl_mk_subsumption_checker.h"
|
||||
#include "muz/base/fixedpoint_params.hpp"
|
||||
#include "muz/base/fp_params.hpp"
|
||||
#include "tactic/generic_model_converter.h"
|
||||
|
||||
|
||||
|
@ -39,8 +39,8 @@ namespace datalog {
|
|||
|
||||
|
||||
bool mk_subsumption_checker::is_total_rule(const rule * r) {
|
||||
if (r->get_tail_size() != 0) {
|
||||
return false;
|
||||
if (r->get_tail_size() != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned pt_len = r->get_positive_tail_size();
|
||||
|
@ -113,7 +113,7 @@ namespace datalog {
|
|||
}
|
||||
|
||||
|
||||
bool mk_subsumption_checker::transform_rule(rule * r,
|
||||
bool mk_subsumption_checker::transform_rule(rule * r,
|
||||
rule_subsumption_index& subs_index, rule_ref & res)
|
||||
{
|
||||
unsigned u_len = r->get_uninterpreted_tail_size();
|
||||
|
@ -133,7 +133,7 @@ namespace datalog {
|
|||
if(m_total_relations.contains(tail_atom->get_decl())
|
||||
|| subs_index.is_subsumed(tail_atom)) {
|
||||
if(neg) {
|
||||
//rule contains negated total relation, this means that it is unsatisfiable
|
||||
//rule contains negated total relation, this means that it is unsatisfiable
|
||||
//and can be removed
|
||||
return false;
|
||||
}
|
||||
|
@ -143,8 +143,8 @@ namespace datalog {
|
|||
}
|
||||
}
|
||||
if(!neg && head.get()==tail_atom) {
|
||||
//rule contains its head positively in the tail, therefore
|
||||
//it will never add any new facts to the relation, so it
|
||||
//rule contains its head positively in the tail, therefore
|
||||
//it will never add any new facts to the relation, so it
|
||||
//can be removed
|
||||
return false;
|
||||
}
|
||||
|
@ -197,9 +197,9 @@ namespace datalog {
|
|||
if (m_total_relations.contains(head_pred)) {
|
||||
if (!orig.is_output_predicate(head_pred) ||
|
||||
total_relations_with_included_rules.contains(head_pred)) {
|
||||
//We just skip definitions of total non-output relations as
|
||||
//We just skip definitions of total non-output relations as
|
||||
//we'll eliminate them from the problem.
|
||||
//We also skip rules of total output relations for which we have
|
||||
//We also skip rules of total output relations for which we have
|
||||
//already output the rule which implies their totality.
|
||||
modified = true;
|
||||
continue;
|
||||
|
@ -286,7 +286,7 @@ namespace datalog {
|
|||
obj_hashtable<app> * head_store;
|
||||
if(m_ground_unconditional_rule_heads.find(pred, head_store)) {
|
||||
//Some relations may receive facts by ground unconditioned rules.
|
||||
//We scanned for those earlier, so now we check whether we cannot get a
|
||||
//We scanned for those earlier, so now we check whether we cannot get a
|
||||
//better estimate of relation size from these.
|
||||
|
||||
unsigned gnd_rule_cnt = head_store->size();
|
||||
|
@ -334,7 +334,7 @@ namespace datalog {
|
|||
|
||||
rule_set * mk_subsumption_checker::operator()(rule_set const & source) {
|
||||
// TODO mc
|
||||
if (!m_context.get_params ().xform_subsumption_checker())
|
||||
if (!m_context.get_params ().xform_subsumption_checker())
|
||||
return nullptr;
|
||||
|
||||
m_have_new_total_rule = false;
|
||||
|
@ -366,6 +366,5 @@ namespace datalog {
|
|||
|
||||
return res;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@ Revision History:
|
|||
#include "muz/transforms/dl_mk_scale.h"
|
||||
#include "muz/transforms/dl_mk_array_eq_rewrite.h"
|
||||
#include "muz/transforms/dl_mk_array_instantiation.h"
|
||||
#include "muz/base/fixedpoint_params.hpp"
|
||||
#include "muz/base/fp_params.hpp"
|
||||
|
||||
namespace datalog {
|
||||
|
||||
|
@ -72,7 +72,7 @@ namespace datalog {
|
|||
transf.register_plugin(alloc(datalog::mk_rule_inliner, ctx, 34970));
|
||||
transf.register_plugin(alloc(datalog::mk_coi_filter, ctx, 34960));
|
||||
transf.register_plugin(alloc(datalog::mk_interp_tail_simplifier, ctx, 34950));
|
||||
|
||||
|
||||
if (ctx.get_params().datalog_subsumption()) {
|
||||
transf.register_plugin(alloc(datalog::mk_subsumption_checker, ctx, 34940));
|
||||
transf.register_plugin(alloc(datalog::mk_rule_inliner, ctx, 34930));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue