3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-08 18:31:49 +00:00

working on horn difference logic

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2013-04-21 18:17:49 -07:00
parent 17f0377c06
commit 0fbdd37e89
13 changed files with 105 additions and 41 deletions

View file

@ -46,7 +46,7 @@ extern "C" {
Z3_TRY;
LOG_Z3_mk_int_symbol(c, i);
RESET_ERROR_CODE();
if (i < 0 || (unsigned)i >= (SIZE_MAX >> PTR_ALIGNMENT)) {
if (i < 0 || (size_t)i >= (SIZE_MAX >> PTR_ALIGNMENT)) {
SET_ERROR_CODE(Z3_IOB);
return 0;
}

View file

@ -268,6 +268,8 @@ public:
bool is_int_real(expr const * n) const { return is_int_real(get_sort(n)); }
MATCH_UNARY(is_uminus);
MATCH_UNARY(is_to_real);
MATCH_UNARY(is_to_int);
MATCH_BINARY(is_sub);
MATCH_BINARY(is_add);
MATCH_BINARY(is_mul);

View file

@ -1004,7 +1004,6 @@ namespace datalog {
symbol is_name(_name.str().c_str());
std::stringstream _name2;
_name2 << "get_succ#" << i;
symbol acc_name(_name2.str().c_str());
ptr_vector<accessor_decl> accs;
type_ref tr(0);
accs.push_back(mk_accessor_decl(name, tr));

View file

@ -647,7 +647,6 @@ namespace datalog {
}
}
ast_manager& m = get_manager();
datalog::rule_manager& rm = get_rule_manager();
contains_pred contains_p(*this);
check_pred check_pred(contains_p, get_manager());

View file

@ -141,7 +141,6 @@ namespace datalog {
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) {
rule_manager& rm = m_context.get_rule_manager();
bool found = false;
for (unsigned j = 0; !found && j < num; ++j) {
found = m_util.is_mkbv(args[j]);

View file

@ -35,6 +35,8 @@ Revision History:
#include"dl_mk_karr_invariants.h"
#include"expr_safe_replace.h"
#include"bool_rewriter.h"
#include"dl_mk_backwards.h"
#include"dl_mk_loop_counter.h"
namespace datalog {
@ -199,6 +201,29 @@ namespace datalog {
return 0;
}
}
mk_loop_counter lc(m_ctx);
mk_backwards bwd(m_ctx);
scoped_ptr<rule_set> src_loop = lc(source);
TRACE("dl", src_loop->display(tout << "source loop\n"););
// run propagation forwards, then backwards
scoped_ptr<rule_set> src_annot = update_using_propagation(*src_loop, *src_loop);
TRACE("dl", src_annot->display(tout << "updated using propagation\n"););
#if 0
// figure out whether to update same rules as used for saturation.
scoped_ptr<rule_set> rev_source = bwd(*src_annot);
src_annot = update_using_propagation(*src_annot, *rev_source);
#endif
rule_set* rules = lc.revert(*src_annot);
rules->inherit_predicates(source);
TRACE("dl", rules->display(tout););
return rules;
}
rule_set* mk_karr_invariants::update_using_propagation(rule_set const& src, rule_set const& srcref) {
m_inner_ctx.reset();
rel_context& rctx = m_inner_ctx.get_rel_context();
ptr_vector<func_decl> heads;
@ -207,24 +232,24 @@ namespace datalog {
m_inner_ctx.register_predicate(*fit, false);
}
m_inner_ctx.ensure_opened();
m_inner_ctx.replace_rules(source);
m_inner_ctx.replace_rules(srcref);
m_inner_ctx.close();
rule_set::decl2rules::iterator dit = source.begin_grouped_rules();
rule_set::decl2rules::iterator dend = source.end_grouped_rules();
rule_set::decl2rules::iterator dit = srcref.begin_grouped_rules();
rule_set::decl2rules::iterator dend = srcref.end_grouped_rules();
for (; dit != dend; ++dit) {
heads.push_back(dit->m_key);
}
m_inner_ctx.rel_query(heads.size(), heads.c_ptr());
rule_set* rules = alloc(rule_set, m_ctx);
it = source.begin();
rule_set* dst = alloc(rule_set, m_ctx);
rule_set::iterator it = src.begin(), end = src.end();
for (; it != end; ++it) {
update_body(rctx, *rules, **it);
update_body(rctx, *dst, **it);
}
if (m_ctx.get_model_converter()) {
add_invariant_model_converter* kmc = alloc(add_invariant_model_converter, m);
rule_set::decl2rules::iterator git = source.begin_grouped_rules();
rule_set::decl2rules::iterator gend = source.end_grouped_rules();
rule_set::decl2rules::iterator git = src.begin_grouped_rules();
rule_set::decl2rules::iterator gend = src.end_grouped_rules();
for (; git != gend; ++git) {
func_decl* p = git->m_key;
expr_ref fml(m);
@ -236,9 +261,9 @@ namespace datalog {
}
m_ctx.add_model_converter(kmc);
}
TRACE("dl", rules->display(tout););
rules->inherit_predicates(source);
return rules;
dst->inherit_predicates(src);
return dst;
}
void mk_karr_invariants::update_body(rel_context& rctx, rule_set& rules, rule& r) {

View file

@ -56,7 +56,7 @@ namespace datalog {
context m_inner_ctx;
arith_util a;
void update_body(rel_context& rctx, rule_set& result, rule& r);
rule_set* update_using_propagation(rule_set const& src, rule_set const& srcref);
public:
mk_karr_invariants(context & ctx, unsigned priority);

View file

@ -32,7 +32,7 @@ namespace datalog {
mk_loop_counter::~mk_loop_counter() { }
app_ref mk_loop_counter::add_arg(app* fn, unsigned idx) {
app_ref mk_loop_counter::add_arg(rule_set const& src, rule_set& dst, app* fn, unsigned idx) {
expr_ref_vector args(m);
func_decl* new_fn, *old_fn = fn->get_decl();
args.append(fn->get_num_args(), fn->get_args());
@ -46,17 +46,29 @@ namespace datalog {
m_old2new.insert(old_fn, new_fn);
m_new2old.insert(new_fn, old_fn);
m_refs.push_back(new_fn);
m_ctx.register_predicate(new_fn, false);
if (src.is_output_predicate(old_fn)) {
dst.set_output_predicate(new_fn);
}
}
return app_ref(m.mk_app(new_fn, args.size(), args.c_ptr()), m);
}
app_ref mk_loop_counter::del_arg(app* fn) {
expr_ref_vector args(m);
func_decl* old_fn, *new_fn = fn->get_decl();
SASSERT(fn->get_num_args() > 0);
args.append(fn->get_num_args()-1, fn->get_args());
VERIFY (m_new2old.find(new_fn, old_fn));
return app_ref(m.mk_app(old_fn, args.size(), args.c_ptr()), m);
}
rule_set * mk_loop_counter::operator()(rule_set const & source) {
m_refs.reset();
m_old2new.reset();
m_new2old.reset();
context& ctx = source.get_context();
rule_manager& rm = source.get_rule_manager();
rule_set * result = alloc(rule_set, ctx);
rule_set * result = alloc(rule_set, m_ctx);
unsigned sz = source.get_num_rules();
rule_ref new_rule(rm);
app_ref_vector tail(m);
@ -71,16 +83,14 @@ namespace datalog {
unsigned utsz = r.get_uninterpreted_tail_size();
unsigned tsz = r.get_tail_size();
for (unsigned j = 0; j < utsz; ++j, ++cnt) {
tail.push_back(add_arg(r.get_tail(j), cnt));
tail.push_back(add_arg(source, *result, r.get_tail(j), cnt));
neg.push_back(r.is_neg_tail(j));
m_ctx.register_predicate(tail.back()->get_decl(), false);
}
for (unsigned j = utsz; j < tsz; ++j) {
tail.push_back(r.get_tail(j));
neg.push_back(false);
}
head = add_arg(r.get_head(), cnt);
m_ctx.register_predicate(head->get_decl(), false);
head = add_arg(source, *result, r.get_head(), cnt);
// set the loop counter to be an increment of the previous
bool found = false;
unsigned last = head->get_num_args()-1;
@ -108,9 +118,41 @@ namespace datalog {
// model converter: remove references to extra argument.
// proof converter: remove references to extra argument as well.
result->inherit_predicates(source);
return result;
}
rule_set * mk_loop_counter::revert(rule_set const & source) {
context& ctx = source.get_context();
rule_manager& rm = source.get_rule_manager();
rule_set * result = alloc(rule_set, ctx);
unsigned sz = source.get_num_rules();
rule_ref new_rule(rm);
app_ref_vector tail(m);
app_ref head(m);
svector<bool> neg;
for (unsigned i = 0; i < sz; ++i) {
tail.reset();
neg.reset();
rule & r = *source.get_rule(i);
unsigned utsz = r.get_uninterpreted_tail_size();
unsigned tsz = r.get_tail_size();
for (unsigned j = 0; j < utsz; ++j) {
tail.push_back(del_arg(r.get_tail(j)));
neg.push_back(r.is_neg_tail(j));
}
for (unsigned j = utsz; j < tsz; ++j) {
tail.push_back(r.get_tail(j));
neg.push_back(false);
}
head = del_arg(r.get_head());
new_rule = rm.mk(head, tail.size(), tail.c_ptr(), neg.c_ptr(), r.name(), true);
result->add_rule(new_rule);
}
// model converter: ...
// proof converter: ...
return result;
}
};

View file

@ -32,7 +32,8 @@ namespace datalog {
obj_map<func_decl, func_decl*> m_new2old;
obj_map<func_decl, func_decl*> m_old2new;
app_ref add_arg(app* fn, unsigned idx);
app_ref add_arg(rule_set const& src, rule_set& dst, app* fn, unsigned idx);
app_ref del_arg(app* fn);
public:
mk_loop_counter(context & ctx, unsigned priority = 33000);
~mk_loop_counter();
@ -40,6 +41,8 @@ namespace datalog {
rule_set * operator()(rule_set const & source);
func_decl* get_old(func_decl* f) const { return m_new2old.find(f); }
rule_set * revert(rule_set const& source);
};
};

View file

@ -409,9 +409,10 @@ namespace datalog {
}
void rule_set::reopen() {
SASSERT(is_closed());
m_stratifier = 0;
m_deps.reset();
if (is_closed()) {
m_stratifier = 0;
m_deps.reset();
}
}
/**

View file

@ -1643,7 +1643,3 @@ public:
#endif /* _DIFF_LOGIC_H_ */
#if 0
#endif

View file

@ -318,7 +318,7 @@ template<typename Ext>
void theory_diff_logic<Ext>::assign_eh(bool_var v, bool is_true) {
m_stats.m_num_assertions++;
atom * a = 0;
m_bool_var2atom.find(v, a);
VERIFY (m_bool_var2atom.find(v, a));
SASSERT(a);
SASSERT(get_context().get_assignment(v) != l_undef);
SASSERT((get_context().get_assignment(v) == l_true) == is_true);
@ -376,13 +376,6 @@ final_check_status theory_diff_logic<Ext>::final_check_eh() {
SASSERT(is_consistent());
#if 0
TBD:
if (propagate_cheap_equalities()) {
return FC_CONTINUE;
}
#endif
if (m_non_diff_logic_exprs) {
return FC_GIVEUP;
}

View file

@ -223,6 +223,7 @@ class inf_rational {
}
friend inline inf_rational operator*(const rational & r1, const inf_rational & r2);
friend inline inf_rational operator*(const inf_rational & r1, const rational & r2);
friend inline inf_rational operator/(const inf_rational & r1, const rational & r2);
inf_rational & operator++() {
@ -426,6 +427,10 @@ inline inf_rational operator*(const rational & r1, const inf_rational & r2) {
return result;
}
inline inf_rational operator*(const inf_rational & r1, const rational & r2) {
return r2 * r1;
}
inline inf_rational operator/(const inf_rational & r1, const rational & r2) {
inf_rational result(r1);
result.m_first /= r2;