format * visit(format * n, format * const * children) { if (is_app_of(n, m_fid, OP_LINE_BREAK)) return mk_string(m_manager, " "); else if (is_app_of(n, m_fid, OP_LINE_BREAK_EXT)) return mk_string(m_manager, n->get_decl()->get_parameter(0).get_symbol().bare_str()); else if (is_app_of(n, m_fid, OP_CHOICE)) return to_app(n->get_arg(0)); else return m_manager.mk_app(n->get_decl(), n->get_num_args(), (expr *const*) children); }
void bv_decl_plugin::get_offset_term(app * a, expr * & t, rational & offset) const { family_id fid = get_family_id(); if (a->get_num_args() == 2 && is_app_of(a, fid, OP_BADD) && is_app_of(a->get_arg(0), fid, OP_BV_NUM)) { unsigned sz; func_decl * decl = to_app(a->get_arg(0))->get_decl(); offset = decl->get_parameter(0).get_rational(); sz = decl->get_parameter(1).get_int(); t = a->get_arg(1); offset = mod(offset, rational::power_of_two(sz)); } else { t = a; offset = rational(0); } }
Z3_bool Z3_API Z3_fpa_get_numeral_sign(Z3_context c, Z3_ast t, int * sgn) { Z3_TRY; LOG_Z3_fpa_get_numeral_sign(c, t, sgn); RESET_ERROR_CODE(); CHECK_NON_NULL(t, 0); CHECK_VALID_AST(t, 0); if (sgn == nullptr) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } scoped_mpf val(mpfm); bool r = plugin->is_numeral(to_expr(t), val); if (!r || mpfm.is_nan(val)) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } *sgn = mpfm.sgn(val); return r; Z3_CATCH_RETURN(0); }
bool Z3_API Z3_is_as_array(Z3_context c, Z3_ast a) { Z3_TRY; LOG_Z3_is_as_array(c, a); RESET_ERROR_CODE(); return a && is_expr(to_ast(a)) && is_app_of(to_expr(a), mk_c(c)->get_array_fid(), OP_AS_ARRAY); Z3_CATCH_RETURN(false); }
bool float_decl_plugin::is_value(expr * n, mpf & val) { if (is_app_of(n, m_family_id, OP_FLOAT_VALUE)) { m_fm.set(val, m_values[to_app(n)->get_decl()->get_parameter(0).get_ext_id()]); return true; } return false; }
Z3_ast Z3_API Z3_fpa_get_numeral_sign_bv(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_fpa_get_numeral_sign_bv(c, t); RESET_ERROR_CODE(); CHECK_NON_NULL(t, nullptr); CHECK_VALID_AST(t, nullptr); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); api::context * ctx = mk_c(c); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } scoped_mpf val(mpfm); bool r = plugin->is_numeral(to_expr(t), val); if (!r || mpfm.is_nan(val)) { SET_ERROR_CODE(Z3_INVALID_ARG); return nullptr; } app * a; if (mpfm.is_pos(val)) a = ctx->bvutil().mk_numeral(0, 1); else a = ctx->bvutil().mk_numeral(1, 1); mk_c(c)->save_ast_trail(a); RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(nullptr); }
Z3_string Z3_API Z3_fpa_get_numeral_significand_string(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_fpa_get_numeral_significand_string(c, t); RESET_ERROR_CODE(); CHECK_NON_NULL(t, nullptr); CHECK_VALID_AST(t, nullptr); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); SASSERT(plugin != 0); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); return ""; } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) { SET_ERROR_CODE(Z3_INVALID_ARG); return ""; } unsigned sbits = val.get().get_sbits(); scoped_mpq q(mpqm); mpqm.set(q, mpfm.sig(val)); if (!mpfm.is_denormal(val)) mpqm.add(q, mpfm.m_powers2(sbits - 1), q); mpqm.div(q, mpfm.m_powers2(sbits - 1), q); if (mpfm.is_inf(val)) mpqm.set(q, 0); std::stringstream ss; mpqm.display_decimal(ss, q, sbits); return mk_c(c)->mk_external_string(ss.str()); Z3_CATCH_RETURN(""); }
Z3_ast Z3_API Z3_fpa_get_numeral_significand_bv(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_fpa_get_numeral_significand_bv(c, t); RESET_ERROR_CODE(); CHECK_NON_NULL(t, nullptr); CHECK_VALID_AST(t, nullptr); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); SASSERT(plugin != 0); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } unsigned sbits = val.get().get_sbits(); scoped_mpq q(mpqm); mpqm.set(q, mpfm.sig(val)); if (mpfm.is_inf(val)) mpqm.set(q, 0); app * a = mk_c(c)->bvutil().mk_numeral(q.get(), sbits-1); mk_c(c)->save_ast_trail(a); RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(nullptr); }
/** \brief Try to "unify" t1 and t2 Examples (+ 2 a) (+ 3 a) --> 2, 3, a (+ 2 a) a --> 2, 0, a ... */ bool unify_core(app * t1, expr * t2, expr_ref & new_t1, expr_ref & new_t2, expr_ref & c, bool & first) { if (t1->get_num_args() != 2) return false; expr * a1 = t1->get_arg(0); expr * b1 = t1->get_arg(1); if (t2 == b1) { if (get_neutral_elem(t1, new_t2)) { new_t1 = a1; c = b1; first = false; return true; } } else if (t2 == a1) { if (get_neutral_elem(t1, new_t2)) { new_t1 = b1; c = a1; first = true; return true; } } else if (is_app_of(t2, t1->get_decl()) && to_app(t2)->get_num_args() == 2) { expr * a2 = to_app(t2)->get_arg(0); expr * b2 = to_app(t2)->get_arg(1); if (b1 == b2) { new_t1 = a1; new_t2 = a2; c = b2; first = false; return true; } if (a1 == a2) { new_t1 = b1; new_t2 = b2; c = a1; first = true; return true; } if (t1->get_decl()->is_commutative()) { if (a1 == b2) { new_t1 = b1; new_t2 = a2; c = a1; first = true; // doesn't really matter for commutative ops. return true; } if (b1 == a2) { new_t1 = a1; new_t2 = b2; c = b1; first = false; // doesn't really matter for commutative ops. return true; } } } return false; }
Z3_func_decl Z3_API Z3_get_as_array_func_decl(Z3_context c, Z3_ast a) { Z3_TRY; LOG_Z3_get_as_array_func_decl(c, a); RESET_ERROR_CODE(); if (a && is_expr(to_ast(a)) && is_app_of(to_expr(a), mk_c(c)->get_array_fid(), OP_AS_ARRAY)) { RETURN_Z3(of_func_decl(to_func_decl(to_app(a)->get_decl()->get_parameter(0).get_ast()))); } else { SET_ERROR_CODE(Z3_INVALID_ARG, nullptr); RETURN_Z3(nullptr); } Z3_CATCH_RETURN(nullptr); }
bool float_decl_plugin::is_rm_value(expr * n, mpf_rounding_mode & val) { if (is_app_of(n, m_family_id, OP_RM_NEAREST_TIES_TO_AWAY)) { val = MPF_ROUND_NEAREST_TAWAY; return true; } else if (is_app_of(n, m_family_id, OP_RM_NEAREST_TIES_TO_EVEN)) { val = MPF_ROUND_NEAREST_TEVEN; return true; } else if (is_app_of(n, m_family_id, OP_RM_TOWARD_NEGATIVE)) { val = MPF_ROUND_TOWARD_NEGATIVE; return true; } else if (is_app_of(n, m_family_id, OP_RM_TOWARD_POSITIVE)) { val = MPF_ROUND_TOWARD_POSITIVE; return true; } else if (is_app_of(n, m_family_id, OP_RM_TOWARD_ZERO)) { val = MPF_ROUND_TOWARD_ZERO; return true; } return 0; }
Z3_bool Z3_API Z3_fpa_get_numeral_exponent_int64(Z3_context c, Z3_ast t, int64_t * n, Z3_bool biased) { Z3_TRY; LOG_Z3_fpa_get_numeral_exponent_int64(c, t, n, biased); RESET_ERROR_CODE(); CHECK_NON_NULL(t, 0); CHECK_VALID_AST(t, 0); if (n == nullptr) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); SASSERT(plugin != 0); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); *n = 0; return 0; } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) { SET_ERROR_CODE(Z3_INVALID_ARG); *n = 0; return 0; } unsigned ebits = val.get().get_ebits(); if (biased) { *n = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.bias_exp(ebits, mpfm.exp(val)); } else { *n = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.is_denormal(val) ? mpfm.mk_min_exp(ebits) : mpfm.exp(val); } return 1; Z3_CATCH_RETURN(0); }
Z3_string Z3_API Z3_fpa_get_numeral_exponent_string(Z3_context c, Z3_ast t, Z3_bool biased) { Z3_TRY; LOG_Z3_fpa_get_numeral_exponent_string(c, t, biased); RESET_ERROR_CODE(); CHECK_NON_NULL(t, nullptr); CHECK_VALID_AST(t, nullptr); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); SASSERT(plugin != 0); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); return ""; } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) { SET_ERROR_CODE(Z3_INVALID_ARG); return ""; } unsigned ebits = val.get().get_ebits(); mpf_exp_t exp; if (biased) { exp = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.bias_exp(ebits, mpfm.exp(val)); } else { exp = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.is_denormal(val) ? mpfm.mk_min_exp(ebits) : mpfm.exp(val); } std::stringstream ss; ss << exp; return mk_c(c)->mk_external_string(ss.str()); Z3_CATCH_RETURN(""); }
Z3_ast Z3_API Z3_fpa_get_numeral_exponent_bv(Z3_context c, Z3_ast t, Z3_bool biased) { Z3_TRY; LOG_Z3_fpa_get_numeral_exponent_bv(c, t, biased); RESET_ERROR_CODE(); CHECK_NON_NULL(t, nullptr); CHECK_VALID_AST(t, nullptr); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(nullptr); } unsigned ebits = val.get().get_ebits(); mpf_exp_t exp; if (biased) { exp = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.bias_exp(ebits, mpfm.exp(val)); } else { exp = mpfm.is_zero(val) ? 0 : mpfm.is_inf(val) ? mpfm.mk_top_exp(ebits) : mpfm.is_denormal(val) ? mpfm.mk_min_exp(ebits) : mpfm.exp(val); } app * a = mk_c(c)->bvutil().mk_numeral(exp, ebits); mk_c(c)->save_ast_trail(a); RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(nullptr); }
Z3_bool Z3_API Z3_is_array_value(Z3_context c, Z3_model _m, Z3_ast _v, unsigned* size) { Z3_TRY; LOG_Z3_is_array_value(c, _m, _v, size); RESET_ERROR_CODE(); CHECK_NON_NULL(_v, Z3_FALSE); CHECK_NON_NULL(_m, Z3_FALSE); model * m = to_model_ref(_m); expr * v = to_expr(_v); ast_manager& mgr = mk_c(c)->m(); family_id afid = mk_c(c)->get_array_fid(); unsigned sz = 0; array_util pl(mgr); if (pl.is_as_array(v)) { func_decl* f = pl.get_as_array_func_decl(to_app(v)); func_interp* g = m->get_func_interp(f); sz = g->num_entries(); if (sz > 0 && g->get_arity() != 1) { return Z3_FALSE; } } else { while (pl.is_store(v)) { if (to_app(v)->get_num_args() != 3) { return Z3_FALSE; } v = to_app(v)->get_arg(0); ++sz; } if (!is_app_of(v, afid, OP_CONST_ARRAY)) { return Z3_FALSE; } } if (size) { *size = sz; } return Z3_TRUE; Z3_CATCH_RETURN(Z3_FALSE); }
Z3_bool Z3_API Z3_fpa_get_numeral_significand_uint64(Z3_context c, Z3_ast t, uint64_t * n) { Z3_TRY; LOG_Z3_fpa_get_numeral_significand_uint64(c, t, n); RESET_ERROR_CODE(); CHECK_NON_NULL(t, 0); CHECK_VALID_AST(t, 0); if (n == nullptr) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpautil().fm(); unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); family_id fid = mk_c(c)->get_fpa_fid(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid); SASSERT(plugin != 0); expr * e = to_expr(t); if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) { SET_ERROR_CODE(Z3_INVALID_ARG); *n = 0; return 0; } scoped_mpf val(mpfm); bool r = plugin->is_numeral(e, val); const mpz & z = mpfm.sig(val); if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val)) || !mpzm.is_uint64(z)) { SET_ERROR_CODE(Z3_INVALID_ARG); *n = 0; return 0; } *n = mpzm.get_uint64(z); return 1; Z3_CATCH_RETURN(0); }
bool float_decl_plugin::is_value(expr * n, mpf & val) { if (is_app_of(n, m_family_id, OP_FLOAT_VALUE)) { m_fm.set(val, m_values[to_app(n)->get_decl()->get_parameter(0).get_ext_id()]); return true; } else if (is_app_of(n, m_family_id, OP_FLOAT_MINUS_INF)) { unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); m_fm.mk_ninf(ebits, sbits, val); return true; } else if (is_app_of(n, m_family_id, OP_FLOAT_PLUS_INF)) { unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); m_fm.mk_pinf(ebits, sbits, val); return true; } else if (is_app_of(n, m_family_id, OP_FLOAT_NAN)) { unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); m_fm.mk_nan(ebits, sbits, val); return true; } else if (is_app_of(n, m_family_id, OP_FLOAT_PLUS_ZERO)) { unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); m_fm.mk_pzero(ebits, sbits, val); return true; } else if (is_app_of(n, m_family_id, OP_FLOAT_MINUS_ZERO)) { unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); m_fm.mk_nzero(ebits, sbits, val); return true; } return false; }
bool bv_decl_plugin::is_value(app* e) const { return is_app_of(e, m_family_id, OP_BV_NUM); }
void macro_substitution::cleanup() { reset(); m_decl2macro.finalize(); if (proofs_enabled()) m_decl2macro_pr->finalize(); if (unsat_core_enabled()) m_decl2macro_dep->finalize(); } void macro_substitution::insert(func_decl * f, quantifier * q, proof * pr, expr_dependency * dep) { DEBUG_CODE({ app * body = to_app(q->get_expr()); SASSERT(m_manager.is_eq(body) || m_manager.is_iff(body)); expr * lhs = body->get_arg(0); expr * rhs = body->get_arg(1); SASSERT(is_app_of(lhs, f) || is_app_of(rhs, f)); }); obj_map<func_decl, quantifier *>::obj_map_entry * entry = m_decl2macro.insert_if_not_there2(f, 0); if (entry->get_data().m_value == 0) { // new entry m_manager.inc_ref(f); m_manager.inc_ref(q); entry->get_data().m_value = q; if (proofs_enabled()) { SASSERT(!m_decl2macro_pr->contains(f)); m_decl2macro_pr->insert(f, pr); m_manager.inc_ref(pr); } if (unsat_core_enabled()) { SASSERT(!m_decl2macro_dep->contains(f)); m_decl2macro_dep->insert(f, dep);
void Z3_API Z3_get_array_value(Z3_context c, Z3_model _m, Z3_ast _v, unsigned num_entries, Z3_ast indices[], Z3_ast values[], Z3_ast* else_value) { Z3_TRY; LOG_Z3_get_array_value(c, _m, _v, num_entries, indices, values, else_value); RESET_ERROR_CODE(); CHECK_NON_NULL(_m, ); model * m = to_model_ref(_m); expr* v = to_expr(_v); family_id afid = mk_c(c)->get_array_fid(); ast_manager& mgr = mk_c(c)->m(); array_util pl(mgr); // // note: _v is already reference counted. // saving the trail for the returned values // is redundant. // unsigned sz = 0; if (pl.is_as_array(v)) { func_decl* f = pl.get_as_array_func_decl(to_app(v)); func_interp* g = m->get_func_interp(f); sz = g->num_entries(); if (g->get_arity() != 1) { SET_ERROR_CODE(Z3_INVALID_ARG); return; } for (unsigned i = 0; i < sz && i < num_entries; ++i) { indices[i] = of_ast(g->get_entry(i)->get_arg(0)); values[i] = of_ast(g->get_entry(i)->get_result()); } if (else_value) { *else_value = of_ast(g->get_else()); } } else { while (sz <= num_entries && is_app_of(v, afid, OP_STORE)) { app* a = to_app(v); if (a->get_num_args() != 3) { SET_ERROR_CODE(Z3_INVALID_ARG); return; } expr* idx = a->get_arg(1); expr* val = a->get_arg(2); indices[sz] = of_ast(idx); values[sz] = of_ast(val); v = to_app(v)->get_arg(0); ++sz; } if (is_app_of(v, afid, OP_CONST_ARRAY)) { if (else_value) { *else_value = of_ast(to_app(v)->get_arg(0)); } } else { SET_ERROR_CODE(Z3_INVALID_ARG); return; } } RETURN_Z3_get_array_value; Z3_CATCH; }