z3-z3-4.13.0.src.muz.transforms.dl_mk_array_instantiation.cpp Maven / Gradle / Ivy
The newest version!
/*++
Module Name:
dl_mk_array_instantiation.h
Abstract:
Does array instantiation
Author:
Julien Braine
Revision History:
--*/
#include "muz/transforms/dl_mk_array_instantiation.h"
#include "muz/base/dl_context.h"
#include "ast/pattern/pattern_inference.h"
#include "muz/base/dl_context.h"
#include "ast/rewriter/expr_safe_replace.h"
#include "ast/expr_abstract.h"
#include "muz/base/fp_params.hpp"
namespace datalog {
mk_array_instantiation::mk_array_instantiation(
context & ctx, unsigned priority):
plugin(priority),
m(ctx.get_manager()),
m_ctx(ctx),
m_a(m),
eq_classes(m),
ownership(m)
{
}
rule_set * mk_array_instantiation::operator()(rule_set const & source) {
#if 0
std::cout<<"Array Instantiation called with parameters :"
<<" enforce="< result = alloc(rule_set, m_ctx);
dst = result.get();
unsigned nbrules = source.get_num_rules();
src_manager = &source.get_rule_manager();
for(unsigned i = 0; i < nbrules; i++) {
rule & r = *source.get_rule(i);
instantiate_rule(r, *result);
}
#if 0
std::cout<<"\n\nOutput rules = \n";
result->display(std::cout);
#endif
return result.detach();
}
void mk_array_instantiation::instantiate_rule(const rule& r, rule_set & dest) {
//Reset everything
selects.reset();
eq_classes.reset();
cnt = src_manager->get_counter().get_max_rule_var(r)+1;
done_selects.reset();
ownership.reset();
expr_ref_vector phi(m);
expr_ref_vector preds(m);
expr_ref new_head = create_head(to_app(r.get_head()));
unsigned nb_predicates = r.get_uninterpreted_tail_size();
unsigned tail_size = r.get_tail_size();
for(unsigned i=0;i::iterator it = done_selects.begin(); it!=done_selects.end(); ++it) {
expr_ref tmp(m);
tmp = &it->get_key();
new_tail.push_back(m.mk_eq(it->get_value(), tmp));
}
proof_ref pr(m);
src_manager->mk_rule(m.mk_implies(m.mk_and(new_tail.size(), new_tail.data()), new_head), pr, dest, r.name());
}
expr_ref mk_array_instantiation::create_head(app* old_head) {
expr_ref_vector new_args(m);
for(unsigned i=0;iget_num_args();i++) {
expr*arg = old_head->get_arg(i);
if(m_a.is_array(arg->get_sort())) {
for(unsigned k=0; k< m_ctx.get_params().xform_instantiate_arrays_nb_quantifier();k++) {
expr_ref_vector dummy_args(m);
dummy_args.push_back(arg);
for(unsigned i=0;iget_sort());i++) {
dummy_args.push_back(m.mk_var(cnt, get_array_domain(arg->get_sort(), i)));
cnt++;
}
expr_ref select(m);
select = m_a.mk_select(dummy_args.size(), dummy_args.data());
new_args.push_back(select);
selects.insert_if_not_there(arg, ptr_vector());
selects[arg].push_back(select);
}
if(!m_ctx.get_params().xform_instantiate_arrays_enforce())
new_args.push_back(arg);
}
else
new_args.push_back(arg);
}
return create_pred(old_head, new_args);
}
void mk_array_instantiation::retrieve_selects(expr* e) {
//If the expression is not a function application, we ignore it
if (!is_app(e)) {
return;
}
app*f=to_app(e);
//Call the function recursively on all arguments
unsigned nbargs = f->get_num_args();
for(unsigned i=0;iget_arg(i));
}
//If it is a select, then add it to selects
if(m_a.is_select(f)) {
SASSERT(!m_a.is_array(e->get_sort()));
selects.insert_if_not_there(f->get_arg(0), ptr_vector());
selects[f->get_arg(0)].push_back(e);
}
//If it is a condition between arrays, for example the result of a store, then add it to the equiv_classes
if(m_a.is_store(f)) {
eq_classes.merge(e, f->get_arg(0));
}
else if(m.is_eq(f) && m_a.is_array(f->get_arg(0)->get_sort())) {
eq_classes.merge(f->get_arg(0), f->get_arg(1));
}
}
expr_ref_vector mk_array_instantiation::getId(app*old_pred, const expr_ref_vector& n_args)
{
expr_ref_vector res(m);
for(unsigned i=0;iget_num_args();j++) {
res.push_back(select->get_arg(j));
}
}
}
return res;
}
expr_ref mk_array_instantiation::create_pred(app*old_pred, expr_ref_vector& n_args)
{
expr_ref_vector new_args(m);
new_args.append(n_args);
new_args.append(getId(old_pred, n_args));
for(unsigned i=0;iget_sort());
expr_ref res(m);
func_decl_ref fun_decl(m);
fun_decl = m.mk_func_decl(symbol((old_pred->get_decl()->get_name().str()+"!inst").c_str()), new_sorts.size(), new_sorts.data(), old_pred->get_decl()->get_range());
m_ctx.register_predicate(fun_decl, false);
if(src_set->is_output_predicate(old_pred->get_decl()))
dst->set_output_predicate(fun_decl);
res=m.mk_app(fun_decl,new_args.size(), new_args.data());
return res;
}
var * mk_array_instantiation::mk_select_var(expr* select)
{
var*result;
if(!done_selects.find(select, result)) {
ownership.push_back(select);
result = m.mk_var(cnt, select->get_sort());
cnt++;
done_selects.insert(select, result);
}
return result;
}
expr_ref mk_array_instantiation::rewrite_select(expr*array, expr*select)
{
app*s = to_app(select);
expr_ref res(m);
expr_ref_vector args(m);
args.push_back(array);
for(unsigned i=1; iget_num_args();i++) {
args.push_back(s->get_arg(i));
}
res = m_a.mk_select(args.size(), args.data());
return res;
}
expr_ref_vector mk_array_instantiation::retrieve_all_selects(expr*array)
{
expr_ref_vector all_selects(m);
for(expr_equiv_class::iterator it = eq_classes.begin(array);
it != eq_classes.end(array); ++it) {
selects.insert_if_not_there(*it, ptr_vector());
ptr_vector& select_ops = selects[*it];
for(unsigned i=0;iget_sort());i++) {
dummy_args.push_back(m.mk_var(cnt, get_array_domain(array->get_sort(), i)));
cnt++;
}
all_selects.push_back(m_a.mk_select(dummy_args.size(), dummy_args.data()));
}
return all_selects;
}
expr_ref_vector mk_array_instantiation::instantiate_pred(app*old_pred)
{
unsigned nb_old_args=old_pred->get_num_args();
//Stores, for each old position, the list of a new possible arguments
vector arg_correspondance;
for(unsigned i=0;iget_arg(i), m);
if(m_a.is_array(arg->get_sort())) {
vector arg_possibilities(m_ctx.get_params().xform_instantiate_arrays_nb_quantifier(), retrieve_all_selects(arg));
arg_correspondance.append(arg_possibilities);
if(!m_ctx.get_params().xform_instantiate_arrays_enforce()) {
expr_ref_vector tmp(m);
tmp.push_back(arg);
arg_correspondance.push_back(tmp);
}
}
else {
expr_ref_vector tmp(m);
tmp.push_back(arg);
arg_correspondance.push_back(tmp);
}
}
//Now, we need to deal with every combination
expr_ref_vector res(m);
svector chosen(arg_correspondance.size(), 0u);
while(true) {
expr_ref_vector new_args(m);
for(unsigned i=0;i=arg_correspondance[pos].size());
chosen[pos]++;
}
}
}