Example #1
0
    void variable_intersection::populate_self(const app * a)
    {
        SASSERT(is_uninterp(a));

        //TODO: optimize quadratic complexity
        //TODO: optimize number of checks when variable occurs multiple times
        unsigned arity = a->get_num_args();
        for(unsigned i1=0; i1<arity; i1++) {
            expr * e1=a->get_arg(i1);
            if(is_var(e1)) {
                var* v1=to_var(e1);
                for(unsigned i2=i1+1; i2<arity; i2++) {
                    expr * e2=a->get_arg(i2);
                    if(!is_var(e2)) {
                        continue;
                    }
                    var* v2=to_var(e2);
                    if(v1->get_idx()==v2->get_idx()) {
                        add_pair(i1, i2);
                    }
                }
            }
            else {
                SASSERT(is_app(e1));
                app * c1 = to_app(e1);
                SASSERT(c1->get_num_args()==0); //c1 must be a constant

                m_const_indexes.push_back(i1);
                m_consts.push_back(c1);

                SASSERT(m_const_indexes.size()==m_consts.size());
            }
        }
    }
Example #2
0
 void mk_new_rule_tail(ast_manager & m, app * pred, var_idx_set const & non_local_vars, unsigned & next_idx, varidx2var_map & varidx2var, 
                       sort_ref_buffer & new_rule_domain, expr_ref_buffer & new_rule_args, app_ref & new_pred) {
     expr_ref_buffer new_args(m);
     unsigned n  = pred->get_num_args();
     for (unsigned i = 0; i < n; i++) {
         expr * arg = pred->get_arg(i);
         if (m.is_value(arg)) {
             new_args.push_back(arg);
         }
         else {
             SASSERT(is_var(arg));
             int vidx      = to_var(arg)->get_idx();
             var * new_var = 0;
             if (!varidx2var.find(vidx, new_var)) {
                 new_var = m.mk_var(next_idx, to_var(arg)->get_sort());
                 next_idx++;
                 varidx2var.insert(vidx, new_var);
                 if (non_local_vars.contains(vidx)) {
                     // other predicates used this variable... so it should be in the domain of the filter
                     new_rule_domain.push_back(to_var(arg)->get_sort());
                     new_rule_args.push_back(new_var);
                 }
             }
             SASSERT(new_var != 0);
             new_args.push_back(new_var);
         }
     }
     new_pred = m.mk_app(pred->get_decl(), new_args.size(), new_args.c_ptr());
 }
Example #3
0
 bool visit_children(expr * n, unsigned delta) {
     bool visited = true;
     unsigned dw;
     unsigned j;
     switch (n->get_kind()) {
     case AST_VAR:
         dw = m_window <= UINT_MAX - delta ? m_window + delta : UINT_MAX;
         if (to_var(n)->get_idx() >= delta && to_var(n)->get_idx() <= dw)
             m_contains = true;
         break;
     case AST_APP:
         j = to_app(n)->get_num_args();
         while (j > 0) {
             --j;
             visit(to_app(n)->get_arg(j), delta, visited);
         }
         break;
     case AST_QUANTIFIER:
         if (delta <= UINT_MAX - to_quantifier(n)->get_num_decls()) {
             visit(to_quantifier(n)->get_expr(), delta + to_quantifier(n)->get_num_decls(), visited);
         }
     break;
     default:
         break;
     }
     return visited;
 }
Example #4
0
/**
   \brief Find bounds of the form

   (<= x k)
   (<= (+ x (* -1 y)) k)
   (<= (+ x (* -1 t)) k)  
   (<= (+ t (* -1 x)) k)

   x and y are a bound variables, t is a ground term and k is a numeral

   It also detects >=, and the atom can be negated.
*/
bool elim_bounds::is_bound(expr * n, var * & lower, var * & upper) {
    upper    = 0;
    lower    = 0;
    bool neg = false;
    if (m_manager.is_not(n)) {
        n   = to_app(n)->get_arg(0);
        neg = true;
    }

    bool le  = false;
    if (m_util.is_le(n)) {
        SASSERT(m_util.is_numeral(to_app(n)->get_arg(1)));
        n  = to_app(n)->get_arg(0);
        le = true;
    }
    else if (m_util.is_ge(n)) {
        SASSERT(m_util.is_numeral(to_app(n)->get_arg(1)));
        n  = to_app(n)->get_arg(0);
        le = false;
    }
    else {
        return false;
    }

    if (neg)
        le = !le;
    
    if (is_var(n)) {
        upper = to_var(n);
    }
    else if (m_util.is_add(n) && to_app(n)->get_num_args() == 2) {
        expr * arg1 = to_app(n)->get_arg(0);
        expr * arg2 = to_app(n)->get_arg(1);
        if (is_var(arg1)) 
            upper   = to_var(arg1);
        else if (!is_ground(arg1))
            return false;
        rational k;
        bool is_int;
        if (m_util.is_mul(arg2) && m_util.is_numeral(to_app(arg2)->get_arg(0), k, is_int) && k.is_minus_one()) {
            arg2    = to_app(arg2)->get_arg(1);
            if (is_var(arg2))
                lower = to_var(arg2);
            else if (!is_ground(arg2))
                return false; // not supported
        }
        else {
            return false; // not supported
        }
    }
    else {
        return false;
    }

    if (!le)
        std::swap(upper, lower);
    
    return true;
}
Example #5
0
/**
   \brief Find bounds of the form

   (<= x k)
   (<= (+ x (* -1 y)) k)
   (<= (+ x (* -1 t)) k)
   (<= (+ t (* -1 x)) k)

   x and y are a bound variables, t is a ground term and k is a numeral

   It also detects >=, and the atom can be negated.
*/
bool elim_bounds_cfg::is_bound(expr * n, var * & lower, var * & upper) {
    upper    = nullptr;
    lower    = nullptr;
    bool neg = false;
    if (m.is_not(n)) {
        n   = to_app(n)->get_arg(0);
        neg = true;
    }

    expr* l = nullptr, *r = nullptr;
    bool le  = false;
    if (m_util.is_le(n, l, r) && m_util.is_numeral(r)) {
        n  = l;
        le = true;
    }
    else if (m_util.is_ge(n, l, r) && m_util.is_numeral(r)) {
        n  = l;
        le = false;
    }
    else {
        return false;
    }

    if (neg)
        le = !le;

    if (is_var(n)) {
        upper = to_var(n);
    }
    else if (m_util.is_add(n, l, r)) {
        expr * arg1 = l;
        expr * arg2 = r;
        if (is_var(arg1))
            upper   = to_var(arg1);
        else if (!is_ground(arg1))
            return false;
        rational k;
        bool is_int;
        if (m_util.is_mul(arg2) && m_util.is_numeral(to_app(arg2)->get_arg(0), k, is_int) && k.is_minus_one()) {
            arg2    = to_app(arg2)->get_arg(1);
            if (is_var(arg2))
                lower = to_var(arg2);
            else if (!is_ground(arg2))
                return false; // not supported
        }
        else {
            return false; // not supported
        }
    }
    else {
        return false;
    }

    if (!le)
        std::swap(upper, lower);

    return true;
}
Example #6
0
bool matcher::operator()(expr * e1, expr * e2, substitution & s) {
    reset();
    m_subst = &s;
    m_todo.push_back(expr_pair(e1, e2));
    while (!m_todo.empty()) {
        expr_pair const & p = m_todo.back();
        // if (m_cache.contains(p)) {
        //    m_todo.pop_back();
        //    continue;
        // }

        if (is_var(p.first)) {
            expr_offset r;
            if (m_subst->find(to_var(p.first), 0, r)) {
                if (r.get_expr() != p.second)
                    return false;
            }
            else {
                m_subst->insert(to_var(p.first), 0, expr_offset(p.second, 1));
            }
            m_todo.pop_back();
            continue;
        }


        if (is_var(p.second))
            return false;
        if (!is_app(p.first))
            return false;
        if (!is_app(p.second))
            return false;

        app * n1 = to_app(p.first);
        app * n2 = to_app(p.second);

        if (n1->get_decl() != n2->get_decl())
            return false;

        unsigned num_args1 = n1->get_num_args();
        if (num_args1 != n2->get_num_args())
            return false;

        m_todo.pop_back();

        if (num_args1 == 0)
            continue;
        
        // m_cache.insert(p);
        unsigned j = num_args1;
        while (j > 0) {
            --j;
            m_todo.push_back(expr_pair(n1->get_arg(j), n2->get_arg(j)));
        }
    }
    return true;
}
Example #7
0
unsigned var_counter::get_max_var(bool& has_var) {
    has_var = false;
    unsigned max_var = 0;
    ptr_vector<quantifier> qs;
    while (!m_todo.empty()) {
        expr* e = m_todo.back();
        m_todo.pop_back();
        if (m_visited.is_marked(e)) {
            continue;
        }
        m_visited.mark(e, true);
        switch(e->get_kind()) {
        case AST_QUANTIFIER: {
            qs.push_back(to_quantifier(e));
            break;                 
        }
        case AST_VAR: {
            if (to_var(e)->get_idx() >= max_var) {
                has_var = true;
                max_var = to_var(e)->get_idx();
            }
            break;
        }
        case AST_APP: {
            app* a = to_app(e);
            for (unsigned i = 0; i < a->get_num_args(); ++i) {
                m_todo.push_back(a->get_arg(i));
            }
            break;
        }
        default:
            UNREACHABLE();
            break;
        }
    }
    m_visited.reset();

    while (!qs.empty()) {
        var_counter aux_counter;
        quantifier* q = qs.back();
        qs.pop_back();
        aux_counter.m_todo.push_back(q->get_expr());
        bool has_var1 = false;
        unsigned max_v = aux_counter.get_max_var(has_var1);
        if (max_v >= max_var + q->get_num_decls()) {
            max_var = max_v - q->get_num_decls();
            has_var = has_var || has_var1;                
        }
    }

    return max_var;
}
Example #8
0
bool fpa_util::contains_floats(ast * a) {
    switch (a->get_kind()) {
    case AST_APP: {
        app * aa = to_app(a);
        if (contains_floats(aa->get_decl()))
            return true;
        else
            for (unsigned i = 0; i < aa->get_num_args(); i++)
                if (contains_floats(aa->get_arg(i)))
                    return true;
        break;
    }
    case AST_VAR:
        return contains_floats(to_var(a)->get_sort());
        break;
    case AST_QUANTIFIER: {
        quantifier * q = to_quantifier(a);
        for (unsigned i = 0; i < q->get_num_children(); i++)
            if (contains_floats(q->get_child(i)))
                return true;
        for (unsigned i = 0; i < q->get_num_decls(); i++)
            if (contains_floats(q->get_decl_sort(i)))
                return true;
        if (contains_floats(q->get_expr()))
            return true;
        break;
    }
    case AST_SORT: {
        sort * s = to_sort(a);
        if (is_float(s) || is_rm(s))
            return true;
        else {
            for (unsigned i = 0; i < s->get_num_parameters(); i++) {
                parameter const & pi = s->get_parameter(i);
                if (pi.is_ast() && contains_floats(pi.get_ast()))
                    return true;
            }
        }
        break;
    }
    case AST_FUNC_DECL: {
        func_decl * f = to_func_decl(a);
        for (unsigned i = 0; i < f->get_arity(); i++)
            if (contains_floats(f->get_domain(i)))
                return true;
        if (contains_floats(f->get_range()))
            return true;
        for (unsigned i = 0; i < f->get_num_parameters(); i++) {
            parameter const & pi = f->get_parameter(i);
            if (pi.is_ast() && contains_floats(pi.get_ast()))
                return true;
        }
        break;
    }
    default:
        UNREACHABLE();
    }

    return false;
}
Example #9
0
 bool udoc_relation::is_var_range(expr* e, unsigned& hi, unsigned& lo, unsigned& v) const {
     udoc_plugin& p = get_plugin();
     if (is_var(e)) {
         v = to_var(e)->get_idx();
         hi = p.num_sort_bits(e)-1;
         lo = 0;
         return true;
     }
     expr* e2;
     if (p.bv.is_extract(e, lo, hi, e2) && is_var(e2)) {
         v = to_var(e2)->get_idx();
         SASSERT(lo <= hi);
         return true;
     }
     return false;
 }
    void mk_unbound_compressor::detect_tasks(unsigned rule_index) {
        rule * r = m_rules.get(rule_index);
        var_idx_set tail_vars;
        collect_tail_vars(m_manager, r, tail_vars);

        app * head = r->get_head();
        func_decl * head_pred = head->get_decl();
        if (m_context.is_output_predicate(head_pred)) {
            //we don't compress output predicates
            return;
        }

        unsigned n = head_pred->get_arity();

        var_counter head_var_counter;
        head_var_counter.count_vars(m_manager, head, 1);

        for (unsigned i=0; i<n; i++) {
            expr * arg = head->get_arg(i);
            if (!is_var(arg)) {
                continue;
            }
            unsigned var_idx = to_var(arg)->get_idx();
            if (!tail_vars.contains(var_idx)) {
                //unbound

                unsigned occurence_cnt = head_var_counter.get(var_idx);
                SASSERT(occurence_cnt>0);
                if (occurence_cnt == 1) {
                    TRACE("dl", r->display(m_context, tout << "Compress: "););
                    add_task(head_pred, i);
                    return; //we compress out the unbound arguments one by one
                }
Example #11
0
void unifier::save_var(expr_offset const & p, expr_offset const & t) {
    expr * n = p.get_expr();
    if (is_var(n)) {
        unsigned off = p.get_offset();
        m_subst->insert(to_var(n)->get_idx(), off, t);
    }
}
Example #12
0
 void mk_magic_sets::adornment::populate(app * lit, const var_idx_set & bound_vars) {
     SASSERT(empty());
     unsigned arity = lit->get_num_args();
     for (unsigned i = 0; i < arity; i++) {
         const expr * arg = lit->get_arg(i);
         bool bound = !is_var(arg) || bound_vars.contains(to_var(arg)->get_idx());
         push_back(bound ? AD_BOUND : AD_FREE);
     }
 }
Example #13
0
 unsigned var_counter::get_max_var(bool& has_var) {
     has_var = false;
     unsigned max_var = 0;
     while (!m_todo.empty()) {
         expr* e = m_todo.back();
         unsigned scope = m_scopes.back();
         m_todo.pop_back();
         m_scopes.pop_back();
         if (m_visited.is_marked(e)) {
             continue;
         }
         m_visited.mark(e, true);
         switch(e->get_kind()) {
         case AST_QUANTIFIER: {
             quantifier* q = to_quantifier(e);
             m_todo.push_back(q->get_expr());
             m_scopes.push_back(scope + q->get_num_decls());
             break;                 
         }
         case AST_VAR: {
             if (to_var(e)->get_idx() >= scope + max_var) {
                 has_var = true;
                 max_var = to_var(e)->get_idx() - scope;
             }
             break;
         }
         case AST_APP: {
             app* a = to_app(e);
             for (unsigned i = 0; i < a->get_num_args(); ++i) {
                 m_todo.push_back(a->get_arg(i));
                 m_scopes.push_back(scope);                    
             }
             break;
         }
         default:
             UNREACHABLE();
             break;
         }
     }
     m_visited.reset();
     return max_var;
 }
Example #14
0
 void operator()(var * v) {
     unsigned idx = to_var(v)->get_idx();
     if (idx >= m_num_bindings) {
         warning_msg("free variables cannot be used in patterns.");
         m_result = false;
         return;
     }
     if (idx < m_num_new_bindings) {
         m_found_a_var = true;
         m_found_vars.insert(idx);
     }
 }
Example #15
0
        bool reduce_arg(expr* a, expr_ref& result) {

            sort* s = get_sort(a);
            if (!m_imp.is_fd(s)) {
                return false;
            }
            unsigned bv_size = get_bv_size(s);

            if (is_var(a)) {
                result = m.mk_var(to_var(a)->get_idx(), m_bv.mk_sort(bv_size));
                return true;
            }
            SASSERT(is_app(a));
            func_decl* f = to_app(a)->get_decl();
            if (m_dt.is_constructor(f)) {
                unsigned idx = m_dt.get_constructor_idx(f);
                result = m_bv.mk_numeral(idx, bv_size);
            }
            else if (is_uninterp_const(a)) {
                func_decl* f_fresh;
                if (m_imp.m_enum2bv.find(f, f_fresh)) {
                    result = m.mk_const(f_fresh);
                    return true;
                }

                // create a fresh variable, add bounds constraints for it.
                unsigned nc = m_dt.get_datatype_num_constructors(s);
                result = m.mk_fresh_const(f->get_name().str().c_str(), m_bv.mk_sort(bv_size));
                f_fresh = to_app(result)->get_decl();
                if (!is_power_of_two(nc) || nc == 1) {
                    m_imp.m_bounds.push_back(m_bv.mk_ule(result, m_bv.mk_numeral(nc-1, bv_size)));
                }                
                expr_ref f_def(m);
                ptr_vector<func_decl> const& cs = *m_dt.get_datatype_constructors(s);
                f_def = m.mk_const(cs[nc-1]);
                for (unsigned i = nc - 1; i > 0; ) {
                    --i;
                    f_def = m.mk_ite(m.mk_eq(result, m_bv.mk_numeral(i,bv_size)), m.mk_const(cs[i]), f_def);
                }
                m_imp.m_enum2def.insert(f, f_def);
                m_imp.m_enum2bv.insert(f, f_fresh);
                m_imp.m_bv2enum.insert(f_fresh, f);
                m_imp.m_enum_consts.push_back(f);
                m_imp.m_enum_bvs.push_back(f_fresh);
                m_imp.m_enum_defs.push_back(f_def);
            }
            else {
                throw_non_fd(a);
            }
            ++m_imp.m_num_translated;
            return true;
        }
Example #16
0
 float mk_magic_sets::get_unbound_cost(app * lit, const var_idx_set & bound_vars) {
     func_decl * pred = lit->get_decl();
     float res = 1;
     unsigned n = lit->get_num_args();
     for (unsigned i = 0; i < n; i++) {
         const expr * arg = lit->get_arg(i);
         if (is_var(arg) && !bound_vars.contains(to_var(arg)->get_idx())) {
             res *= m_context.get_sort_size_estimate(pred->get_domain(i));
         }
         //res-=1;
     }
     return res;
 }
Example #17
0
 unsigned get_bound_arg_count(app * lit, const var_idx_set & bound_vars) {
     unsigned res = 0;
     unsigned n = lit->get_num_args();
     for (unsigned i = 0; i < n; i++) {
         const expr * arg = lit->get_arg(i);
         if (!is_var(arg) || bound_vars.contains(to_var(arg)->get_idx())) {
             SASSERT(is_var(arg) || is_app(arg));
             SASSERT(!is_app(arg) || to_app(arg)->get_num_args()==0);
             res++;
         }
     }
     return res;
 }
    bool mk_unbound_compressor::is_unbound_argument(rule * r, unsigned head_index) {
        app * head = r->get_head();
        expr * head_arg = head->get_arg(head_index);
        if (!is_var(head_arg)) {
            return false;
        }
        unsigned var_idx = to_var(head_arg)->get_idx();

        var_idx_set tail_vars;
        collect_tail_vars(m_manager, r, tail_vars);

        return tail_vars.contains(var_idx);
    }
Example #19
0
void quick_checker::collector::collect_core(app * n, func_decl * p, unsigned i) {
    func_decl * f     = n->get_decl();
    unsigned num_args = n->get_num_args();
    for (unsigned j = 0; j < num_args; j++) {
        expr * arg = n->get_arg(j);
        if (is_var(arg)) {
            unsigned idx = to_var(arg)->get_idx();
            if (idx >= m_num_vars)
                return;
            if (m_already_found[idx] && m_conservative) {
                enode_set & s  = m_candidates[idx];
                enode_set & ns = m_tmp_candidates[idx];
                if (s.empty())
                    continue;
                ns.reset();
                enode_vector::const_iterator it  = m_context.begin_enodes_of(f);
                enode_vector::const_iterator end = m_context.end_enodes_of(f);
                for (; it != end; ++it) {
                    enode * curr = *it;
                    if (m_context.is_relevant(curr) && curr->is_cgr() && check_arg(curr, p, i) && j < curr->get_num_args()) {
                        enode * arg = curr->get_arg(j)->get_root();
                        // intersection
                        if (s.contains(arg))
                            ns.insert(arg);
                    }
                }
                SASSERT(m_conservative);
                s.swap(ns);
            }
            else {
                m_already_found[idx] = true;
                enode_set & s  = m_candidates[idx];
                enode_vector::const_iterator it  = m_context.begin_enodes_of(f);
                enode_vector::const_iterator end = m_context.end_enodes_of(f);
                for (; it != end; ++it) {
                    enode * curr = *it;
                    if (m_context.is_relevant(curr) && curr->is_cgr() && check_arg(curr, p, i) && j < curr->get_num_args()) {
                        enode * arg = curr->get_arg(j)->get_root();
                        s.insert(arg);
                    }
                }
            }
        }
        else {
            if (n->get_family_id() != m_manager.get_basic_family_id())
                collect(arg, n->get_decl(), j);
            else
                collect(arg, 0, 0);
        }
    }
}
Example #20
0
void get_expr_stat(expr * n, expr_stat & r) {
    typedef std::pair<expr *, unsigned> pair;
    buffer<pair> todo;
    todo.push_back(pair(n, 0));
    while (!todo.empty()) {
        pair & p       = todo.back();
        n              = p.first;
        unsigned depth = p.second;
        unsigned j;
        todo.pop_back();
        r.m_sym_count++;
        if (depth > r.m_depth)
            r.m_depth = depth;
        switch (n->get_kind()) {
        case AST_APP:
            j = to_app(n)->get_num_args();
            if (j == 0)
                r.m_const_count++;
            while (j > 0) {
                --j;
                todo.push_back(pair(to_app(n)->get_arg(j), depth + 1));
            }
            break;
        case AST_VAR:
            if (to_var(n)->get_idx() > r.m_max_var_idx) 
                r.m_max_var_idx = to_var(n)->get_idx();
            r.m_ground = false;
            break;
        case AST_QUANTIFIER:
            todo.push_back(pair(to_quantifier(n)->get_expr(), depth+1));
            break;
        default:
            UNREACHABLE();
        }
    }
}
Example #21
0
/**
   \brief Decreate the balance of the given variable.
*/
inline void kbo::dec(expr_offset v) {
    int val;
    unsigned v_idx  = to_var(v.get_expr())->get_idx();
    unsigned offset = v.get_offset();
    if (m_deltas.find(v_idx, offset, val)) {
        if (val == 0) 
            m_num_neg++;
        else if (val == 1)
            m_num_pos--;
        m_deltas.insert(v_idx, offset, val - 1);
    }
    else {
        m_deltas.insert(v_idx, offset, -1);
        m_num_neg ++;
    }
}
Example #22
0
 void mk_coalesce::extract_conjs(expr_ref_vector const& sub, rule const& rl, expr_ref& result) {
     obj_map<expr, unsigned> indices;
     bool_rewriter bwr(m);
     rule_ref r(const_cast<rule*>(&rl), rm);
     ptr_vector<sort> sorts;
     expr_ref_vector revsub(m), conjs(m);
     rl.get_vars(sorts);
     revsub.resize(sorts.size());  
     svector<bool> valid(sorts.size(), true);
     for (unsigned i = 0; i < sub.size(); ++i) {
         expr* e = sub[i];
         sort* s = m.get_sort(e);
         expr_ref w(m.mk_var(i, s), m);
         if (is_var(e)) {
             unsigned v = to_var(e)->get_idx();
             SASSERT(v < valid.size());
             if (sorts[v]) {
                 SASSERT(s == sorts[v]);
                 if (valid[v]) {
                     revsub[v] = w;
                     valid[v] = false;
                 }
                 else {
                     SASSERT(revsub[v].get());
                     SASSERT(m.get_sort(revsub[v].get()) == s);
                     conjs.push_back(m.mk_eq(revsub[v].get(), w));    
                 }
             }
         }
         else {
             SASSERT(m.is_value(e));
             SASSERT(m.get_sort(e) == m.get_sort(w));
             conjs.push_back(m.mk_eq(e, w));
         }
     }
     for (unsigned i = 0; i < sorts.size(); ++i) {
         if (valid[i] && sorts[i] && !revsub[i].get()) {
             revsub[i] = m.mk_var(m_idx++, sorts[i]);
         }
     }
     var_subst vs(m, false);
     for (unsigned i = r->get_uninterpreted_tail_size(); i < r->get_tail_size(); ++i) {
         vs(r->get_tail(i), revsub.size(), revsub.c_ptr(), result);
         conjs.push_back(result);
     }
     bwr.mk_and(conjs.size(), conjs.c_ptr(), result);
 }
Example #23
0
/**
   \brief Increase the balance of the given variable.
*/
inline void kbo::inc(expr_offset v) {
    SASSERT(is_var(v.get_expr()));
    int val;
    unsigned v_idx  = to_var(v.get_expr())->get_idx();
    unsigned offset = v.get_offset();
    if (m_deltas.find(v_idx, offset, val)) {
        if (val == -1) 
            m_num_neg--;
        else if (val == 0)
            m_num_pos++;
        m_deltas.insert(v_idx, offset, val + 1);
    }
    else {
        m_deltas.insert(v_idx, offset, 1);
        m_num_pos ++;
    }
}
Example #24
0
bool kbo::VWBc(expr_offset t, expr_offset target_var) {
    SASSERT(target_var.get_expr() == 0 || is_var(target_var.get_expr()));
    svector<expr_offset> & todo = m_vwbc_todo;
    expr_offset s;
    bool found = false;
    unsigned j;
    SASSERT(todo.empty());
    todo.push_back(t);
    while (!todo.empty()) {
        t        = todo.back();
        if (t == target_var)
            found = true;
        expr * n        = t.get_expr();
        unsigned offset = t.get_offset();
        todo.pop_back();
        switch (n->get_kind()) {
        case AST_VAR:
            if (m_subst && m_subst->find(to_var(n), offset, s))
                todo.push_back(s);
            else if (pos) {
                inc(t);
                m_weight_balance += var_weight();
            }
            else {
                dec(t);
                m_weight_balance -= var_weight();
            }
            break;
        case AST_APP:
            if (pos)
                m_weight_balance += f_weight(to_app(n)->get_decl());
            else
                m_weight_balance -= f_weight(to_app(n)->get_decl());
            j = to_app(n)->get_num_args();
            while (j > 0) {
                --j;
                todo.push_back(expr_offset(to_app(n)->get_arg(j), offset));
            }
            break;
        default:
            UNREACHABLE();
            break;
        }
    }
    return found;
}
bool is_well_formed_vars(ptr_vector<sort>& bound, expr* e) {
    ptr_vector<expr> todo;
    ast_mark mark;
    todo.push_back(e);
    while (!todo.empty()) {
        expr* e = todo.back();
        todo.pop_back();
        if (mark.is_marked(e)) {
            continue;
        }
        mark.mark(e, true);
        if (is_quantifier(e)) {
            quantifier* q = to_quantifier(e);
            unsigned depth = q->get_num_decls();
            bound.append(depth, q->get_decl_sorts());
            if (!is_well_formed_vars(bound, q->get_expr())) {
                return false;
            }
            bound.resize(bound.size()-depth);
        }
        else if (is_app(e)) {
            app* a = to_app(e);
            for (unsigned i = 0; i < a->get_num_args(); ++i) {
                todo.push_back(a->get_arg(i));
            }
        }
        else if (is_var(e)) {
            var* v = to_var(e);
            unsigned index = v->get_idx();
            sort* s = v->get_sort();
            SASSERT(index < bound.size());
            index = bound.size()-1-index;
            if (!bound[index]) {
                bound[index] = s;
            }
            if (bound[index] != s) {
                return false;
            }
        }
        else {
            UNREACHABLE();
        }
    }
    return true;
}
Example #26
0
File: der.cpp Project: delcypher/z3
/**
   \brief Return true if \c e is of the form (not (= VAR t)) or (not (iff VAR t)) or (iff VAR t) or (iff (not VAR) t) or (VAR IDX) or (not (VAR IDX)).
   The last case can be viewed
*/
bool der::is_var_diseq(expr * e, unsigned num_decls, var * & v, expr_ref & t) {
    // (not (= VAR t)) and (not (iff VAR t)) cases
    if (m_manager.is_not(e) && (m_manager.is_eq(to_app(e)->get_arg(0)) || m_manager.is_iff(to_app(e)->get_arg(0)))) {
        app * eq   = to_app(to_app(e)->get_arg(0));
        SASSERT(m_manager.is_eq(eq) || m_manager.is_iff(eq));
        expr * lhs = eq->get_arg(0);
        expr * rhs = eq->get_arg(1);
        if (!is_var(lhs, num_decls) && !is_var(rhs, num_decls))
            return false;
        if (!is_var(lhs, num_decls))
            std::swap(lhs, rhs);
        SASSERT(is_var(lhs, num_decls));
        // Remark: Occurs check is not necessary here... the top-sort procedure will check for cycles...
        // if (occurs(lhs, rhs)) {
        //  return false;
        // }
        v = to_var(lhs);
        t = rhs;
        TRACE("der", tout << mk_pp(e, m_manager) << "\n";);
Example #27
0
    void aig_exporter::collect_var_substs(substitution& subst, const app *h,
        const expr_ref_vector& vars, expr_ref_vector& eqs) {
        for (unsigned i = 0; i < h->get_num_args(); ++i) {
            expr *arg = h->get_arg(i);
            expr *latchvar = get_latch_var(i, vars);

            if (is_var(arg)) {
                var *v = to_var(arg);
                expr_offset othervar;
                if (subst.find(v, 0, othervar)) {
                    eqs.push_back(m.mk_eq(latchvar, othervar.get_expr()));
                } else {
                    subst.insert(v, 0, expr_offset(latchvar, 0));
                }
            } else {
                eqs.push_back(m.mk_eq(latchvar, arg));
            }
        }
    }
Example #28
0
 enode * checker::get_enode_eq_to(expr * n) {
     if (is_var(n)) { 
         unsigned idx = to_var(n)->get_idx();
         if (idx >= m_num_bindings)
             return 0;
         return m_bindings[m_num_bindings - idx - 1];
     }
     if (m_context.e_internalized(n) && m_context.is_relevant(n))
         return m_context.get_enode(n);
     if (!is_app(n) || to_app(n)->get_num_args() == 0)
         return 0;
     enode * r = 0;
     if (n->get_ref_count() > 1 && m_to_enode_cache.find(n, r)) 
         return r;
     r = get_enode_eq_to_core(to_app(n));
     if (n->get_ref_count() > 1)
         m_to_enode_cache.insert(n, r);
     return r;
 }
Example #29
0
/**
   \brief Return true if \c n is an application of the form
   
   (f x_{k_1}, ..., x_{k_n})

   where f is uninterpreted
   n == num_decls
   x_{k_i}'s are variables
   and {k_1, ..., k_n } is equals to the set {0, ..., num_decls-1}
*/
bool macro_util::is_macro_head(expr * n, unsigned num_decls) const {
    if (is_app(n) &&
        !to_app(n)->get_decl()->is_associative() &&
        to_app(n)->get_family_id() == null_family_id &&
        to_app(n)->get_num_args() == num_decls) {
        sbuffer<int> var2pos;
        var2pos.resize(num_decls, -1);
        for (unsigned i = 0; i < num_decls; i++) {
            expr * c = to_app(n)->get_arg(i);
            if (!is_var(c)) 
                return false;
            unsigned idx = to_var(c)->get_idx();
            if (idx >= num_decls || var2pos[idx] != -1)
                return false;
            var2pos[idx] = i;
        }
        return true;
    }
    return false;
}
Example #30
0
    void output_predicate(context & ctx, app * f, std::ostream & out)
    {
        func_decl * pred_decl = f->get_decl();
        unsigned arity = f->get_num_args();

        out << pred_decl->get_name() << '(';

        for (unsigned i = 0; i < arity; i++) {
            expr * arg = f->get_arg(i);
            if (i != 0) {
                out << ',';
            }
            if (is_var(arg)) {
                out << "#" << to_var(arg)->get_idx();
            }
            else {
                out << mk_pp(arg, ctx.get_manager());
            }
        }
        out << ")";
    }