void arith_simplifier_plugin::div_monomial(expr_ref_vector& monomials, numeral const& g) {
    numeral n;
    for (unsigned  i = 0; i < monomials.size(); ++i) {
        expr* e = monomials[i].get();
        if (is_numeral(e, n)) {
            SASSERT((n/g).is_int());
            monomials[i] = mk_numeral(n/g);
        }
        else if (is_mul(e) && is_numeral(to_app(e)->get_arg(0), n)) {
            SASSERT((n/g).is_int());
            monomials[i] = mk_mul(n/g, to_app(e)->get_arg(1));
        }
        else {
            UNREACHABLE();
        }
    }
}
Exemplo n.º 2
0
bool static_features::is_non_linear(expr * e) const {
    if (!is_arith_expr(e))
        return false;
    if (is_numeral(e))
        return true;
    if (m_autil.is_add(e))
        return true; // the non
} 
/**
   \brief Traverse args, and copy the non-numeral exprs to result, and accumulate the 
   value of the numerals in k.
*/
void poly_simplifier_plugin::process_monomial(unsigned num_args, expr * const * args, numeral & k, ptr_buffer<expr> & result) {
    rational v;
    for (unsigned i = 0; i < num_args; i++) {
        expr * arg = args[i];
        if (is_numeral(arg, v))
            k *= v;
        else
            result.push_back(arg);
    }
}
Exemplo n.º 4
0
void arith_simplifier_plugin::get_monomial_gcd(expr_ref_vector& monomials, numeral& g) {
    g = numeral::zero();
    numeral n;
    for (unsigned  i = 0; !g.is_one() && i < monomials.size(); ++i) {
        expr* e = monomials[i].get();
        if (is_numeral(e, n)) {
            g = gcd(abs(n), g);
        }
        else if (is_mul(e) && is_numeral(to_app(e)->get_arg(0), n)) {
            g = gcd(abs(n), g);        
        }
        else {
            g = numeral::one();
            return;
        }
    }
    if (g.is_zero()) {
        g = numeral::one();
    }
}
expr * poly_simplifier_plugin::mk_mul(unsigned num_args, expr * const * args) { 
    SASSERT(num_args > 0);
#ifdef Z3DEBUG
    // check for incorrect use of mk_mul
    set_curr_sort(args[0]);
    SASSERT(!is_zero(args[0]));
    numeral k;
    for (unsigned i = 0; i < num_args; i++) {
        SASSERT(!is_numeral(args[i], k) || !k.is_one());
        SASSERT(i == 0 || !is_numeral(args[i]));
    }
#endif
    if (num_args == 1) 
        return args[0];
    else if (num_args == 2)
        return m_manager.mk_app(m_fid, m_MUL, args[0], args[1]);
    else if (is_numeral(args[0]))
        return m_manager.mk_app(m_fid, m_MUL, args[0], m_manager.mk_app(m_fid, m_MUL, num_args - 1, args+1));
    else
        return m_manager.mk_app(m_fid, m_MUL, num_args, args); 
}
Exemplo n.º 6
0
 // check if n has at most one argument that is not numeral.
 void check_mul(app * n) {
     if (m_nonlinear)
         return; // nothing to check
     unsigned num_args = n->get_num_args();
     bool found_non_numeral = false;
     for (unsigned i = 0; i < num_args; i++) {
         if (!is_numeral(n->get_arg(i))) {
             if (found_non_numeral)
                 fail("logic does not support nonlinear arithmetic");
             else
                 found_non_numeral = true;
         }
     }
 }
/**
   \brief Return true if m is a wellformed monomial.
*/
bool poly_simplifier_plugin::wf_monomial(expr * m) const {
    SASSERT(!is_add(m));
    if (is_mul(m)) {
        app * curr = to_app(m);
        expr * pp  = 0;
        if (is_numeral(curr->get_arg(0)))
            pp = curr->get_arg(1);
        else
            pp = curr;
        if (is_mul(pp)) {
            for (unsigned i = 0; i < to_app(pp)->get_num_args(); i++) {
                expr * arg = to_app(pp)->get_arg(i);
                CTRACE("wf_monomial_bug", is_mul(arg), 
                       tout << "m:  "  << mk_ismt2_pp(m, m_manager) << "\n";
                       tout << "pp: "  << mk_ismt2_pp(pp, m_manager) << "\n";
                       tout << "arg: " << mk_ismt2_pp(arg, m_manager) << "\n";
                       tout << "i:  " << i << "\n";
                       );
                SASSERT(!is_mul(arg));
                SASSERT(!is_numeral(arg));
            }
        }
    }
expr * poly_simplifier_plugin::mk_mul(numeral const & c, expr * body) {
    numeral c_prime, d;
    c_prime = norm(c);
    if (c_prime.is_zero())
        return 0;
    if (body == 0)
        return mk_numeral(c_prime);
    if (c_prime.is_one())
         return body;
    if (is_numeral(body, d)) {
        c_prime = norm(c_prime*d);
        if (c_prime.is_zero())
            return 0;
        return mk_numeral(c_prime);
    }
    set_curr_sort(body);
    expr * args[2] = { mk_numeral(c_prime), body };
    return mk_mul(2, args);
}
Exemplo n.º 9
0
bool static_features::is_diff_atom(expr const * e) const {
    if (!is_bool(e))
        return false;
    if (!m_manager.is_eq(e) && !is_arith_expr(e))
        return false;
    SASSERT(to_app(e)->get_num_args() == 2);
    expr * lhs = to_app(e)->get_arg(0);
    SASSERT(is_numeral(to_app(e)->get_arg(1)));
    // lhs can be 'x' or '(+ x (* -1 y))'
    if (!is_arith_expr(lhs))
        return true;
    SASSERT(is_app(lhs));
    // lhs must be (+ x (* -1 y))
    if (to_app(lhs)->get_decl_kind() != OP_ADD || to_app(lhs)->get_num_args() != 2)
        return false;
    // x
    if (is_arith_expr(to_app(lhs)->get_arg(0)))
        return false;
    expr * arg2 = to_app(lhs)->get_arg(1);
    // arg2: (* -1 y)
    return m_autil.is_mul(arg2) && to_app(arg2)->get_num_args() == 2 && is_minus_one(to_app(arg2)->get_arg(0)) && !is_arith_expr(to_app(arg2)->get_arg(1));
}
Exemplo n.º 10
0
 // check if the divisor is a numeral
 void check_div(app * n) {
     SASSERT(n->get_num_args() == 2);
     if (!m_nonlinear && !is_numeral(n->get_arg(1)))
         fail("logic does not support nonlinear arithmetic");
 }
Exemplo n.º 11
0
rational const & sexpr::get_numeral() const {
    SASSERT(is_numeral() || is_bv_numeral());
    return static_cast<sexpr_numeral const *>(this)->m_val;
}
Exemplo n.º 12
0
bool fpa_decl_plugin::is_numeral(expr * n) {
    scoped_mpf v(m_fm);
    return is_numeral(n, v);
}