func_decl * datatype_decl_plugin::mk_update_field( unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { decl_kind k = OP_DT_UPDATE_FIELD; ast_manager& m = *m_manager; if (num_parameters != 1 || !parameters[0].is_ast()) { m.raise_exception("invalid parameters for datatype field update"); return 0; } if (arity != 2) { m.raise_exception("invalid number of arguments for datatype field update"); return 0; } func_decl* acc = 0; if (is_func_decl(parameters[0].get_ast())) { acc = to_func_decl(parameters[0].get_ast()); } if (acc && !get_util().is_accessor(acc)) { acc = 0; } if (!acc) { m.raise_exception("datatype field update requires a datatype accessor as the second argument"); return 0; } sort* dom = acc->get_domain(0); sort* rng = acc->get_range(); if (dom != domain[0]) { m.raise_exception("first argument to field update should be a data-type"); return 0; } if (rng != domain[1]) { std::ostringstream buffer; buffer << "second argument to field update should be " << mk_ismt2_pp(rng, m) << " instead of " << mk_ismt2_pp(domain[1], m); m.raise_exception(buffer.str().c_str()); return 0; } range = domain[0]; func_decl_info info(m_family_id, k, num_parameters, parameters); return m.mk_func_decl(symbol("update_field"), arity, domain, range, info); }
void operator()(app* n) { ast_manager& m = m_manager; unsigned num_args = n->get_num_args(); ptr_buffer<expr> args; for (unsigned i = 0; i < num_args; ++i) { args.push_back(find(n->get_arg(i))); } if (m_manager.is_eq(n) && m_util.is_array(args[0])) { visit_eq(n); return; } if (m_manager.is_distinct(n) && num_args > 0 && m_util.is_array(args[0])) { ptr_buffer<expr> eqs; for (unsigned i = 0; i < num_args; ++i) { for (unsigned j = i + 1; j < num_args; ++j) { eqs.push_back(m.mk_not(m.mk_eq(args[i], args[j]))); } } insert(n, m.mk_and(eqs.size(), eqs.c_ptr())); return; } if (m_util.is_select(n)) { SASSERT(num_args > 0); // select(store(A,i,v),j) -> ite(i = j, v, select(A,j)) if (m_util.is_store(args[0])) { app* a = to_app(args[0]); expr* b = find(a->get_arg(0)); expr* v = find(a->get_arg(a->get_num_args()-1)); ptr_buffer<expr> eqs; SASSERT(num_args + 1 == a->get_num_args()); for (unsigned i = 1; i < num_args; ++i) { eqs.push_back(m.mk_eq(args[i], find(a->get_arg(i)))); } expr* r = m.mk_ite(m.mk_and(eqs.size(), eqs.c_ptr()), v, mk_select(b, num_args-1, args.c_ptr()+1)); insert(n, r); return; } // select(ite(a,b,c),i) -> ite(a, select(b,i), select(c, i)) if (m.is_ite(args[0])) { app* k = to_app(args[0]); expr* a = k->get_arg(0); expr* b = mk_select(k->get_arg(1), args.size()-1, args.c_ptr()+1); expr* c = mk_select(k->get_arg(2), args.size()-1, args.c_ptr()+1); expr* r = m.mk_ite(a, b, c); insert(n, r); return; } // select(map_f(A,B),i) -> f(select(A,i), select(B,i)) if (m_util.is_map(args[0])) { app* a = to_app(args[0]); func_decl* f = a->get_decl(); SASSERT(f->get_num_parameters() == 1); SASSERT(f->get_parameter(0).is_ast()); SASSERT(is_func_decl(f->get_parameter(0).get_ast())); parameter p = f->get_parameter(0); func_decl* d = to_func_decl(p.get_ast()); ptr_buffer<expr> args2; for (unsigned i = 0; i < a->get_num_args(); ++i) { args2.push_back(mk_select(find(a->get_arg(i)), args.size()-1, args.c_ptr()+1)); } expr* r = m.mk_app(d, args2.size(), args2.c_ptr()); insert(n, r); return; } // select(const v, i) -> v if (m_util.is_const(args[0])) { insert(n, to_app(args[0])->get_arg(0)); return; } } expr* r = m_manager.mk_app(n->get_decl(), args.size(), args.c_ptr()); insert(n, r); }