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);
}
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); 
}
void arith_simplifier_plugin::mk_le_ge_eq_core(expr * arg1, expr * arg2, expr_ref & result) {
    set_curr_sort(arg1);
    bool is_int = m_curr_sort->get_decl_kind() == INT_SORT;
    expr_ref_vector monomials(m_manager);
    rational k;
    TRACE("arith_eq_bug", tout << mk_ismt2_pp(arg1, m_manager) << "\n" << mk_ismt2_pp(arg2, m_manager) << "\n";);