void visit_eq(app* eq) {
     ast_manager& m = m_manager;
     SASSERT(m.is_eq(eq));
     sort* s = m.get_sort(eq->get_arg(0));
     SASSERT(is_sort_of(s, m_fid, ARRAY_SORT));
     // sort* rng = get_array_range(s);
     unsigned arity = get_array_arity(s);
     shift_vars sh(m);
     expr_ref e1(m), e2(m);
     sh(find(eq->get_arg(0)), arity, e1);
     sh(find(eq->get_arg(1)), arity, e2);
     expr_ref_vector args(m);
     buffer<symbol> names;
     ptr_buffer<sort>   sorts;
     args.push_back(e1);
     for (unsigned i = 0; i < arity; ++i) {
         args.push_back(m.mk_var(i, get_array_domain(s, i)));
         sorts.push_back(get_array_domain(s, arity - i - 1));
         names.push_back(symbol(m_offset++));
     }
     e1 = mk_select(args.size(), args.c_ptr());
     args[0] = e2;
     e2 = mk_select(args.size(), args.c_ptr());
     e1 = m.mk_eq(e1, e2);
     
     e1 = m.mk_quantifier(true, arity, sorts.c_ptr(), names.c_ptr(), e1, 1);
     insert(eq, e1);
 }
 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<expr>());
     ptr_vector<expr>& select_ops = selects[*it];
     for(unsigned i=0;i<select_ops.size();i++)
     {
       all_selects.push_back(rewrite_select(array, select_ops[i]));
     }
   }
   if(all_selects.size()==0)
   {
     expr_ref_vector dummy_args(m);
     dummy_args.push_back(array);
     for(unsigned i=0;i<get_array_arity(get_sort(array));i++)
     {
       dummy_args.push_back(m.mk_var(cnt, get_array_domain(get_sort(array), i)));
       cnt++;
     }
     all_selects.push_back(m_a.mk_select(dummy_args.size(), dummy_args.c_ptr()));
   }
   return all_selects;
 }
 expr_ref mk_array_instantiation::create_head(app* old_head)
 {
    expr_ref_vector new_args(m);
    for(unsigned i=0;i<old_head->get_num_args();i++)
    {
      expr*arg = old_head->get_arg(i);
      if(m_a.is_array(get_sort(arg)))
      {
        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;i<get_array_arity(get_sort(arg));i++)
          {
            dummy_args.push_back(m.mk_var(cnt, get_array_domain(get_sort(arg), i)));
            cnt++;
          }
          expr_ref select(m);
          select = m_a.mk_select(dummy_args.size(), dummy_args.c_ptr());
          new_args.push_back(select);
          selects.insert_if_not_there(arg, ptr_vector<expr>());
          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);
 }
Exemplo n.º 4
0
 void check_sort(sort * s) {
     if (s->get_family_id() == null_family_id) {
         if (!m_uf)
             fail("logic does not support uninterpreted sorts");
     }
     else if (m.is_bool(s)) {
         return;
     }
     else if (m_a_util.is_int(s)) {
         if (!m_ints)
             fail("logic does not support integers");
     }
     else if (m_a_util.is_real(s)) {
         if (!m_reals)
             fail("logic does not support reals");
     }
     else if (m_bv_util.is_bv_sort(s)) {
         if (!m_bvs)
             fail("logic does not support bitvectors");
     }
     else if (m_ar_util.is_array(s)) {
         if (m_arrays) {
             return;
         }
         else if (m_bv_arrays) {
             if (get_array_arity(s) != 1)
                 fail("logic supports only unidimensional arrays");
             if (!m_bv_util.is_bv_sort(get_array_range(s)) || !m_bv_util.is_bv_sort(get_array_domain(s, 0)))
                 fail("logic supports only arrays from bitvectors to bitvectors");
         }
         else {
             fail("logic does not support arrays");
         }
     }
 }
Exemplo n.º 5
0
 // return a term that is different from t.
 bool mk_diff(expr * t, expr_ref & r) {
     sort * s = m().get_sort(t);
     if (m().is_bool(s)) {
         r = m().mk_not(t);
         return true;
     }
     family_id fid = s->get_family_id();
     if (fid == m_a_util.get_family_id()) {
         r = m_a_util.mk_add(t, m_a_util.mk_numeral(rational(1), s));
         return true;
     }
     if (fid == m_bv_util.get_family_id()) {
         r = m().mk_app(m_bv_util.get_family_id(), OP_BNOT, t);
         return true;
     }
     if (fid == m_ar_util.get_family_id()) {
         if (m().is_uninterp(get_array_range(s)))
             return false;
         unsigned arity = get_array_arity(s);
         for (unsigned i = 0; i < arity; i++)
             if (m().is_uninterp(get_array_domain(s, i)))
                 return false;
         // building 
         // r = (store t i1 ... in d)
         // where i1 ... in are arbitrary values
         // and d is a term different from (select t i1 ... in)
         ptr_buffer<expr> new_args;
         new_args.push_back(t);
         for (unsigned i = 0; i < arity; i++)
             new_args.push_back(m().get_some_value(get_array_domain(s, i)));
         expr_ref sel(m());
         sel = m().mk_app(fid, OP_SELECT, new_args.size(), new_args.c_ptr());
         expr_ref diff_sel(m());
         if (!mk_diff(sel, diff_sel))
             return false;
         new_args.push_back(diff_sel);
         r = m().mk_app(fid, OP_STORE, new_args.size(), new_args.c_ptr());
         return true;
     }
     if (fid == m_dt_util.get_family_id()) {
         // In the current implementation, I only handle the case where
         // the datatype has a recursive constructor.
         ptr_vector<func_decl> const & constructors = *m_dt_util.get_datatype_constructors(s);
         for (func_decl * constructor : constructors) {
             unsigned num    = constructor->get_arity();
             unsigned target = UINT_MAX;
             for (unsigned i = 0; i < num; i++) {
                 sort * s_arg = constructor->get_domain(i);
                 if (s == s_arg) {
                     target = i;
                     continue;
                 }
                 if (m().is_uninterp(s_arg))
                     break;
             }
             if (target == UINT_MAX)
                 continue;
             // use the constructor the distinct term constructor(...,t,...)
             ptr_buffer<expr> new_args;
             for (unsigned i = 0; i < num; i++) {
                 if (i == target) {
                     new_args.push_back(t);
                 }
                 else {
                     new_args.push_back(m().get_some_value(constructor->get_domain(i)));
                 }
             }
             r = m().mk_app(constructor, new_args.size(), new_args.c_ptr());
             return true;
         }
         // TODO: handle more cases.
         return false;
     }
     return false;
 }