Beispiel #1
0
inline void kbo::VWB(expr_offset t, unsigned idx) {
    expr_offset null(0, 0);
    app * n = to_app(t.get_expr());
    unsigned num = n->get_num_args();
    for (; idx < num; idx++)
        VWBc<pos>(expr_offset(n->get_arg(idx), t.get_offset()), null);
}
Beispiel #2
0
/**
   \brief Check whether the variable in t1 occurs in t2.
*/
bool lpo::occurs(expr_offset const & t1, expr_offset const & t2) {
    SASSERT(is_var(t1.get_expr()));
    if (is_ground(t2.get_expr()))
        return false;
    m_todo.reset();
    m_todo.push_back(t2);
    while (!m_todo.empty()) {
        expr_offset t = m_todo.back();
        m_todo.pop_back();
        t = find(t);
        expr * n        = t.get_expr();
        if (is_ground(n))
            continue;
        unsigned offset = t.get_offset();
        unsigned j;
        switch (n->get_kind()) {
        case AST_VAR:
            if (t == t1)
                return true;
            break;
        case AST_APP:
            j = to_app(n)->get_num_args();
            while (j > 0) {
                --j;
                expr * arg = to_app(n)->get_arg(j);
                if (!is_ground(arg)) 
                    m_todo.push_back(expr_offset(arg, offset));
            }
            break;
        default:
            UNREACHABLE();
        }
    }
    return false;
}
Beispiel #3
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;
}
Beispiel #4
0
/**
   \brief Return true if s >_{lpo} t_i forall children t_i of t.
*/
bool lpo::dominates_args(expr_offset s, expr_offset t, unsigned depth) {
    SASSERT(is_app(t.get_expr()));
    unsigned num_args = to_app(t.get_expr())->get_num_args();
    unsigned off      = t.get_offset();
    for (unsigned i = 0; i < num_args; i++) {
        expr * t_i = to_app(t.get_expr())->get_arg(i);
        if (!greater(s, expr_offset(t_i, off), depth+1))
            return false;
    }
    return true;
}
Beispiel #5
0
/**
   \brief Return true if s_i >=_{lpo} t for some arg s_i of s.
 */
bool lpo::arg_dominates_expr(expr_offset s, expr_offset t, unsigned depth) {
    SASSERT(is_app(s.get_expr()));
    unsigned num_args = to_app(s.get_expr())->get_num_args();
    unsigned off      = s.get_offset();
    for (unsigned i = 0; i < num_args; i++) {
        expr * s_i = to_app(s.get_expr())->get_arg(i);
        result r   = compare(expr_offset(s_i, off), t, depth+1);
        if (r == EQUAL || r == GREATER)
            return true;
    }
    return false;
}
Beispiel #6
0
void tst_match(ast_manager & m, app * t, app * i) {
    substitution s(m);
    s.reserve(2, 10); // reserving a big number of variables to be safe.

    matcher      match;
    std::cout << "Is " << mk_pp(i, m) << " an instance of " << mk_pp(t, m) << "\n";
    if (match(t, i, s)) {
        std::cout << "yes\n";
        s.display(std::cout);
    }
    else {
        std::cout << "no\n";
    }

    s.reset();
    
    if (t->get_decl() == i->get_decl()) {
        // trying to match the arguments of t and i
        std::cout << "Are the arguments of " << mk_pp(i, m) << " an instance of the arguments of " << mk_pp(t, m) << "\n";
        unsigned num_args = t->get_num_args();
        unsigned j;
        for (j = 0; j < num_args; j++) {
            if (!match(t->get_arg(j), i->get_arg(j), s))
                break;
        }
        if (j == num_args) {
            std::cout << "yes\n";
            s.display(std::cout);
            
            // create some dummy term to test for applying the substitution.
            sort_ref S(          m.mk_uninterpreted_sort(symbol("S")),    m);
            sort * domain[3]   = {S, S, S};
            func_decl_ref r(     m.mk_func_decl(symbol("r"), 3, domain, S), m);
            expr_ref x1(         m.mk_var(0, S), m);
            expr_ref x2(         m.mk_var(1, S), m);
            expr_ref x3(         m.mk_var(2, S), m);
            app_ref  rxyzw(      m.mk_app(r, x1.get(), x2.get(), x3.get()), m);
            expr_ref result(m);
            unsigned deltas[2] = {0,0};
            s.apply(2, deltas, expr_offset(rxyzw, 0), result);
            std::cout << "applying substitution to\n" << mk_pp(rxyzw,m) << "\nresult:\n" << mk_pp(result,m) << "\n";
        }
        else {
            std::cout << "no\n";
        }
    }
    
    std::cout << "\n";
}
Beispiel #7
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;
}
Beispiel #8
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;
}
Beispiel #9
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));
            }
        }
    }
Beispiel #10
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";);