Exemplo n.º 1
0
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);
        }