Example #1
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 #2
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;
}
Example #3
0
order::result lpo::lex_compare(expr_offset s, expr_offset t, unsigned depth) {
    SASSERT(is_app(s.get_expr()));
    SASSERT(is_app(t.get_expr()));
    app * _s = to_app(s.get_expr());
    app * _t = to_app(t.get_expr());
    unsigned num_args1 = _s->get_num_args();
    unsigned num_args2 = _t->get_num_args();
    unsigned num_args  = std::min(num_args1, num_args2);
    unsigned off1      = s.get_offset();
    unsigned off2      = t.get_offset();
    result r = EQUAL;
    for (unsigned i = 0; i < num_args; i++) {
        r = compare(expr_offset(_s->get_arg(i), off1), expr_offset(_t->get_arg(i), off2), depth+1);
        if (r != EQUAL)
            break;
    }
    if (r == EQUAL) {
        if (num_args1 > num_args2)
            return GREATER;
        if (num_args1 < num_args2)
            return NOT_GTEQ;
    }
    return r;
}
Example #4
0
        else if (f != g)
            return arg_dominates_expr(s, t, depth) ? GREATER : NOT_GTEQ;
        else {
            result r = lex_compare(s, t, depth);
            if (r == GREATER) {
                if (dominates_args(s, t, depth))
                    return GREATER;
            }
            else if (r == EQUAL)
                return EQUAL;
            return to_app(s.get_expr())->get_num_args() > 1 && arg_dominates_expr(s, t, depth) ? GREATER : NOT_GTEQ;
        }
    }
}

order::result lpo::compare(expr_offset s, expr_offset t, unsigned depth) {
    TRACE("lpo", tout << "comparing:\n" << mk_pp(s.get_expr(), m_manager) << "\n" << mk_pp(t.get_expr(), m_manager) << "\n";);
    result r = compare_core(s, t, depth);
    TRACE("lpo", tout << "result of comparing:\n" << mk_pp(s.get_expr(), m_manager) << "\n" << mk_pp(t.get_expr(), m_manager) << "\nresult: " << r << "\n";);
    return r;
}

bool lpo::greater(expr_offset const & t1, expr_offset const & t2, substitution * s) {
    m_subst = s;
    return greater(t1, t2, static_cast<unsigned>(0));
}

order::result lpo::compare(expr_offset const & t1, expr_offset const & t2, substitution * s) {
    m_subst = s;
    result r = compare(t1, t2, static_cast<unsigned>(0));
    if (r != NOT_GTEQ) 
Example #5
0
order::result kbo::compare(expr_offset const & t1, expr_offset const & t2, substitution * s) {
    reset();
    m_subst = s;

    if (t1 == t2) 
        return EQUAL;

    expr * n1 = t1.get_expr();
    expr * n2 = t2.get_expr();

    // f(s) >_{kbo} f(t) iff s >_{kbo} t
    while (is_unary_app(n1) && is_unary_app(n2) && to_app(n1)->get_decl() == to_app(n2)->get_decl()) {
        n1 = to_app(n1)->get_arg(0);
        n2 = to_app(n2)->get_arg(0);
    }

    svector<entry> & todo = m_compare_todo;
    SASSERT(todo.empty());
    todo.push_back(entry(find(expr_offset(n1, t1.get_offset())),
                         find(expr_offset(n2, t2.get_offset())),
                         0));

    result res = UNKNOWN;

    while (!todo.empty()) {
        entry & e = todo.back();
        expr_offset t1 = e.m_t1;
        expr_offset t2 = e.m_t2;
        expr * n1 = t1.get_expr();
        expr * n2 = t2.get_expr();
        TRACE("kbo", tout << "processing with idx: " << e.m_idx << "\n" << 
              mk_pp(n1, m_manager) << "\n" << mk_pp(n2, m_manager) << "\n";
              tout << "wb : " << m_weight_balance << "\n";);
        SASSERT(!is_quantifier(n1) && !is_quantifier(n2));
        bool v1 = is_var(n1);
        bool v2 = is_var(n2);
        if (v1 && v2) {
            todo.pop_back();
            inc(t1);
            dec(t2);
            res = t1 == t2 ? EQUAL : UNCOMPARABLE;
        }
        else if (v1) {
            todo.pop_back();
            res = VWBc<false>(t2, t1) ? LESSER : UNCOMPARABLE;
            inc(t1);
            m_weight_balance += var_weight();
        }
        else if (v2) {
            todo.pop_back();
            res = VWBc<true>(t1, t2) ? GREATER : UNCOMPARABLE;
            dec(t2);
            m_weight_balance -= var_weight();
        }
        else {
            func_decl * f = to_app(n1)->get_decl();
            func_decl * g = to_app(n2)->get_decl();
            result lex;
            if (f != g || to_app(n1)->get_num_args() != to_app(n2)->get_num_args()) {
                VWB<true>(t1, 0);
                VWB<false>(t2, 0);
                lex = UNCOMPARABLE;
            }
            else {
                unsigned & idx = e.m_idx;
                // when idx > 0, res contains the result for child (idx - 1)
                if (idx > 0 && res != EQUAL) {
                    VWB<true>(t1, idx);
                    VWB<false>(t2, idx);
                    lex = res;
                }
                else if (idx == to_app(n1)->get_num_args()) {
                    // all children were visited
                    lex = EQUAL;
                }
                else if (idx < to_app(n1)->get_num_args()) {
                    expr_offset c1 = find(expr_offset(to_app(n1)->get_arg(idx), t1.get_offset()));
                    expr_offset c2 = find(expr_offset(to_app(n2)->get_arg(idx), t2.get_offset()));
                    idx++; // move curr entry child idx
                    entry new_entry(c1, c2, 0);
                    todo.push_back(new_entry);
                    continue; // process child before continuing
                }
            }
            
            todo.pop_back();
            m_weight_balance += f_weight(f);
            m_weight_balance -= f_weight(g);

            if (m_weight_balance > 0)
                res = no_neg();
            else if (m_weight_balance < 0)
                res = no_pos();
            else if (f_greater(f, g))
                res = no_neg();
            else if (f_greater(g, f))
                res = no_pos();
            else if (f != g)
                res = UNCOMPARABLE;
            else if (lex == EQUAL)
                res = EQUAL;
            else if (lex == GREATER)
                res = no_neg();
            else if (lex == LESSER)
                res = no_pos();
            else
                res = UNCOMPARABLE;
        }
        TRACE("kbo", tout << "result: " << res << "\n";);