3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-08 10:25:18 +00:00

synchronize fork

This commit is contained in:
nilsbecker 2018-07-06 16:17:56 +02:00 committed by nilsbecker
commit 820c14ed06
430 changed files with 19930 additions and 13462 deletions

View file

@ -27,6 +27,24 @@ Version 4.8.0
Use sat.acce=true to enable the full repertoire of inprocessing methods. By default, clauses that are "eliminated" by acce are tagged
as lemmas (redundant) and are garbage collected if their glue level is high.
- Substantial overhaul of the spacer horn clause engine.
- Added basic features to support Lambda bindings.
- Added model compression to eliminate local function definitions in models when
inlining them does not incur substantial overhead. The old behavior, where models are left
uncompressed can be replayed by setting the top-level parameter model_compress=false.
- Integration of a new solver for linear integer arithmetic and mixed linear integer arithmetic by Lev Nachmanson.
It incorporates several improvements to QF_LIA solving based on
. using a better LP engine, which is already the foundation for QF_LRA
. including cuts based on Hermite Normal Form (thanks to approaches described
in "cuts from proofs" and "cutting the mix").
. extracting integer solutions from LP solutions by tightening bounds selectively.
We use a generalization of Bromberger and Weidenbach that allows avoiding selected
bounds tighthenings (https://easychair.org/publications/paper/qGfG).
It solves significantly more problems in the QF_LIA category and may at this point also
be the best solver for your problem as well.
The new solver is enabled only for select SMT-LIB logics. These include QF_LIA, QF_IDL, and QF_UFLIA.
Other theories (still) use the legacy solver for arithmetic. You can enable the new solver by setting
the parameter smt.arith.solver=6 to give it a spin.
- Removed features:
- interpolation API

View file

@ -115,7 +115,6 @@ void prove_example1() {
*/
void prove_example2() {
std::cout << "prove_example1\n";
context c;
expr x = c.int_const("x");
expr y = c.int_const("y");
@ -139,6 +138,7 @@ void prove_example2() {
s.reset();
s.add(!conjecture2);
std::cout << "conjecture 2:\n" << conjecture2 << "\n";
if (s.check() == unsat) {
std::cout << "proved" << "\n";
}

View file

@ -1754,7 +1754,6 @@ void parser_example5() {
err:
printf("Z3 error: %s.\n", Z3_get_error_msg(ctx, e));
if (ctx != NULL) {
printf("Error message: '%s'.\n",Z3_get_parser_error(ctx));
del_solver(ctx, s);
Z3_del_context(ctx);
}

View file

@ -2106,6 +2106,7 @@ namespace test_mapi
Console.WriteLine("OK, model: {0}", s.Model.ToString());
}
public static void TranslationExample()
{
Context ctx1 = new Context();

View file

@ -1482,7 +1482,7 @@ class JavaExample
BoolExpr ca = commAxiom(ctx, g);
BoolExpr thm = ctx.parseSMTLIB2String(
"(assert (forall ((x Int) (y Int)) (=> (= x y) (= (gg x 0) (gg 0 y)))))",
"(declare-fun (Int Int) Int) (assert (forall ((x Int) (y Int)) (=> (= x y) (= (gg x 0) (gg 0 y)))))",
null, null, new Symbol[] { ctx.mkSymbol("gg") },
new FuncDecl[] { g })[0];
System.out.println("formula: " + thm);
@ -2303,7 +2303,7 @@ class JavaExample
p.simplifierExample(ctx);
p.finiteDomainExample(ctx);
p.floatingPointExample1(ctx);
p.floatingPointExample2(ctx);
// core dumps: p.floatingPointExample2(ctx);
}
{ // These examples need proof generation turned on.
@ -2314,7 +2314,7 @@ class JavaExample
p.proveExample2(ctx);
p.arrayExample2(ctx);
p.tupleExample(ctx);
p.parserExample3(ctx);
// throws p.parserExample3(ctx);
p.enumExample(ctx);
p.listExample(ctx);
p.treeExample(ctx);

View file

@ -718,17 +718,11 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
fullname, line))
raise e
# First pass will just generate the tactic factories
idx = 0
for data in ADD_TACTIC_DATA:
fout.write('MK_SIMPLE_TACTIC_FACTORY(__Z3_local_factory_%s, %s);\n' % (idx, data[2]))
idx = idx + 1
fout.write('#define ADD_TACTIC_CMD(NAME, DESCR, FACTORY) ctx.insert(alloc(tactic_cmd, symbol(NAME), DESCR, alloc(FACTORY)))\n')
fout.write('#define ADD_TACTIC_CMD(NAME, DESCR, CODE) ctx.insert(alloc(tactic_cmd, symbol(NAME), DESCR, [](ast_manager &m, const params_ref &p) { return CODE; }))\n')
fout.write('#define ADD_PROBE(NAME, DESCR, PROBE) ctx.insert(alloc(probe_info, symbol(NAME), DESCR, PROBE))\n')
fout.write('void install_tactics(tactic_manager & ctx) {\n')
idx = 0
for data in ADD_TACTIC_DATA:
fout.write(' ADD_TACTIC_CMD("%s", "%s", __Z3_local_factory_%s);\n' % (data[0], data[1], idx))
idx = idx + 1
fout.write(' ADD_TACTIC_CMD("%s", "%s", %s);\n' % data)
for data in ADD_PROBE_DATA:
fout.write(' ADD_PROBE("%s", "%s", %s);\n' % data)
fout.write('}\n')

View file

@ -73,7 +73,7 @@ Type2PyStr = { VOID_PTR : 'ctypes.c_void_p', INT : 'ctypes.c_int', UINT : 'ctype
# Mapping to .NET types
Type2Dotnet = { VOID : 'void', VOID_PTR : 'IntPtr', INT : 'int', UINT : 'uint', INT64 : 'Int64', UINT64 : 'UInt64', DOUBLE : 'double',
FLOAT : 'float', STRING : 'string', STRING_PTR : 'byte**', BOOL : 'int', SYMBOL : 'IntPtr',
FLOAT : 'float', STRING : 'string', STRING_PTR : 'byte**', BOOL : 'byte', SYMBOL : 'IntPtr',
PRINT_MODE : 'uint', ERROR_CODE : 'uint' }
# Mapping to Java types

View file

@ -35,7 +35,7 @@ public:
fail_if_proof_generation("ackermannize", g);
TRACE("ackermannize", g->display(tout << "in\n"););
expr_ref_vector flas(m);
ptr_vector<expr> flas;
const unsigned sz = g->size();
for (unsigned i = 0; i < sz; i++) flas.push_back(g->form(i));
lackr lackr(m, m_p, m_st, flas, nullptr);

View file

@ -134,7 +134,7 @@ void ackr_model_converter::add_entry(model_evaluator & evaluator,
info->abstract(arg, aarg);
expr_ref arg_value(m);
evaluator(aarg, arg_value);
args.push_back(arg_value);
args.push_back(std::move(arg_value));
}
if (fi->get_entry(args.c_ptr()) == nullptr) {
TRACE("ackr_model",

View file

@ -23,8 +23,8 @@
#include "ast/for_each_expr.h"
#include "model/model_smt2_pp.h"
lackr::lackr(ast_manager& m, params_ref p, lackr_stats& st, expr_ref_vector& formulas,
solver * uffree_solver)
lackr::lackr(ast_manager& m, const params_ref& p, lackr_stats& st,
const ptr_vector<expr>& formulas, solver * uffree_solver)
: m_m(m)
, m_p(p)
, m_formulas(formulas)
@ -173,11 +173,10 @@ void lackr::abstract() {
}
m_info->seal();
// perform abstraction of the formulas
const unsigned sz = m_formulas.size();
for (unsigned i = 0; i < sz; ++i) {
for (expr * f : m_formulas) {
expr_ref a(m_m);
m_info->abstract(m_formulas.get(i), a);
m_abstr.push_back(a);
m_info->abstract(f, a);
m_abstr.push_back(std::move(a));
}
}
@ -249,13 +248,9 @@ lbool lackr::lazy() {
// Collect all uninterpreted terms, skipping 0-arity.
//
bool lackr::collect_terms() {
ptr_vector<expr> stack;
ptr_vector<expr> stack = m_formulas;
expr * curr;
expr_mark visited;
for(unsigned i = 0; i < m_formulas.size(); ++i) {
stack.push_back(m_formulas.get(i));
TRACE("lackr", tout << "infla: " <<mk_ismt2_pp(m_formulas.get(i), m_m, 2) << "\n";);
}
while (!stack.empty()) {
curr = stack.back();

View file

@ -42,8 +42,8 @@ struct lackr_stats {
**/
class lackr {
public:
lackr(ast_manager& m, params_ref p, lackr_stats& st,
expr_ref_vector& formulas, solver * uffree_solver);
lackr(ast_manager& m, const params_ref& p, lackr_stats& st,
const ptr_vector<expr>& formulas, solver * uffree_solver);
~lackr();
void updt_params(params_ref const & _p);
@ -82,7 +82,7 @@ class lackr {
typedef ackr_helper::app_set app_set;
ast_manager& m_m;
params_ref m_p;
expr_ref_vector m_formulas;
const ptr_vector<expr>& m_formulas;
expr_ref_vector m_abstr;
fun2terms_map m_fun2terms;
ackr_info_ref m_info;

View file

@ -29,14 +29,14 @@ Notes:
#define CHECK_IS_ALGEBRAIC(ARG, RET) { \
if (!Z3_algebraic_is_value_core(c, ARG)) { \
SET_ERROR_CODE(Z3_INVALID_ARG); \
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr); \
return RET; \
} \
}
#define CHECK_IS_ALGEBRAIC_X(ARG, RET) { \
if (!Z3_algebraic_is_value_core(c, ARG)) { \
SET_ERROR_CODE(Z3_INVALID_ARG); \
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr); \
RETURN_Z3(RET); \
} \
}
@ -196,7 +196,7 @@ extern "C" {
CHECK_IS_ALGEBRAIC_X(b, nullptr);
if ((is_rational(c, b) && get_rational(c, b).is_zero()) ||
(!is_rational(c, b) && am(c).is_zero(get_irrational(c, b)))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
BIN_OP(/,div);
@ -211,7 +211,7 @@ extern "C" {
if (k % 2 == 0) {
if ((is_rational(c, a) && get_rational(c, a).is_neg()) ||
(!is_rational(c, a) && am(c).is_neg(get_irrational(c, a)))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -360,13 +360,13 @@ extern "C" {
expr2polynomial converter(mk_c(c)->m(), pm, nullptr, true);
if (!converter.to_polynomial(to_expr(p), _p, d) ||
static_cast<unsigned>(max_var(_p)) >= n + 1) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
algebraic_numbers::manager & _am = am(c);
scoped_anum_vector as(_am);
if (!to_anum_vector(c, n, a, as)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
scoped_anum_vector roots(_am);
@ -396,13 +396,13 @@ extern "C" {
expr2polynomial converter(mk_c(c)->m(), pm, nullptr, true);
if (!converter.to_polynomial(to_expr(p), _p, d) ||
static_cast<unsigned>(max_var(_p)) >= n) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
algebraic_numbers::manager & _am = am(c);
scoped_anum_vector as(_am);
if (!to_anum_vector(c, n, a, as)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
{

View file

@ -51,7 +51,7 @@ extern "C" {
LOG_Z3_mk_real(c, num, den);
RESET_ERROR_CODE();
if (den == 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
sort* s = mk_c(c)->m().mk_sort(mk_c(c)->get_arith_fid(), REAL_SORT);
@ -97,7 +97,7 @@ extern "C" {
LOG_Z3_mk_sub(c, num_args, args);
RESET_ERROR_CODE();
if (num_args == 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
expr* r = to_expr(args[0]);
@ -120,12 +120,8 @@ extern "C" {
}
Z3_bool Z3_API Z3_is_algebraic_number(Z3_context c, Z3_ast a) {
Z3_TRY;
LOG_Z3_is_algebraic_number(c, a);
RESET_ERROR_CODE();
expr * e = to_expr(a);
return mk_c(c)->autil().is_irrational_algebraic_numeral(e);
Z3_CATCH_RETURN(Z3_FALSE);
return mk_c(c)->autil().is_irrational_algebraic_numeral(to_expr(a)) ? Z3_TRUE : Z3_FALSE;
}
Z3_ast Z3_API Z3_get_algebraic_number_lower(Z3_context c, Z3_ast a, unsigned precision) {
@ -133,7 +129,7 @@ extern "C" {
LOG_Z3_get_algebraic_number_lower(c, a, precision);
RESET_ERROR_CODE();
if (!Z3_is_algebraic_number(c, a)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
expr * e = to_expr(a);
@ -151,7 +147,7 @@ extern "C" {
LOG_Z3_get_algebraic_number_upper(c, a, precision);
RESET_ERROR_CODE();
if (!Z3_is_algebraic_number(c, a)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
expr * e = to_expr(a);
@ -171,7 +167,7 @@ extern "C" {
rational val;
ast * _a = to_ast(a);
if (!is_expr(_a) || !mk_c(c)->autil().is_numeral(to_expr(_a), val)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
expr * r = mk_c(c)->autil().mk_numeral(numerator(val), true);
@ -187,7 +183,7 @@ extern "C" {
rational val;
ast * _a = to_ast(a);
if (!is_expr(_a) || !mk_c(c)->autil().is_numeral(to_expr(_a), val)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
expr * r = mk_c(c)->autil().mk_numeral(denominator(val), true);

View file

@ -47,6 +47,7 @@ extern "C" {
Z3_CATCH_RETURN(nullptr);
}
Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i) {
Z3_TRY;
LOG_Z3_mk_select(c, a, i);
@ -57,7 +58,7 @@ extern "C" {
sort * a_ty = m.get_sort(_a);
sort * i_ty = m.get_sort(_i);
if (a_ty->get_family_id() != mk_c(c)->get_array_fid()) {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
sort * domain[2] = {a_ty, i_ty};
@ -80,7 +81,7 @@ extern "C" {
sort * a_ty = m.get_sort(_a);
// sort * i_ty = m.get_sort(_i);
if (a_ty->get_family_id() != mk_c(c)->get_array_fid()) {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<sort> domain;
@ -99,6 +100,7 @@ extern "C" {
Z3_CATCH_RETURN(nullptr);
}
Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v) {
Z3_TRY;
LOG_Z3_mk_store(c, a, i, v);
@ -111,7 +113,7 @@ extern "C" {
sort * i_ty = m.get_sort(_i);
sort * v_ty = m.get_sort(_v);
if (a_ty->get_family_id() != mk_c(c)->get_array_fid()) {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
sort * domain[3] = {a_ty, i_ty, v_ty};
@ -134,7 +136,7 @@ extern "C" {
sort * a_ty = m.get_sort(_a);
sort * v_ty = m.get_sort(_v);
if (a_ty->get_family_id() != mk_c(c)->get_array_fid()) {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<sort> domain;
@ -155,12 +157,13 @@ extern "C" {
Z3_CATCH_RETURN(nullptr);
}
Z3_ast Z3_API Z3_mk_map(Z3_context c, Z3_func_decl f, unsigned n, Z3_ast const* args) {
Z3_TRY;
LOG_Z3_mk_map(c, f, n, args);
RESET_ERROR_CODE();
if (n == 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ast_manager & m = mk_c(c)->m();
@ -295,7 +298,7 @@ extern "C" {
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(0).get_ast());
RETURN_Z3(r);
}
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
Z3_CATCH_RETURN(nullptr);
}
@ -311,7 +314,7 @@ extern "C" {
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(n-1).get_ast());
RETURN_Z3(r);
}
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
Z3_CATCH_RETURN(nullptr);
}

View file

@ -48,7 +48,7 @@ extern "C" {
LOG_Z3_mk_int_symbol(c, i);
RESET_ERROR_CODE();
if (i < 0 || (size_t)i >= (SIZE_MAX >> PTR_ALIGNMENT)) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return nullptr;
}
Z3_symbol result = of_symbol(symbol(i));
@ -281,7 +281,7 @@ extern "C" {
if (_s.is_numerical()) {
return _s.get_num();
}
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return -1;
Z3_CATCH_RETURN(-1);
}
@ -355,7 +355,7 @@ extern "C" {
LOG_Z3_get_app_decl(c, a);
RESET_ERROR_CODE();
if (!is_app(reinterpret_cast<ast*>(a))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(of_func_decl(to_app(a)->get_decl()));
@ -371,11 +371,11 @@ extern "C" {
LOG_Z3_get_app_arg(c, a, i);
RESET_ERROR_CODE();
if (!is_app(reinterpret_cast<ast*>(a))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
if (i >= to_app(a)->get_num_args()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(of_ast(to_app(a)->get_arg(i)));
@ -398,7 +398,7 @@ extern "C" {
LOG_Z3_get_decl_parameter_kind(c, d, idx);
RESET_ERROR_CODE();
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return Z3_PARAMETER_INT;
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
@ -430,12 +430,12 @@ extern "C" {
LOG_Z3_get_decl_int_parameter(c, d, idx);
RESET_ERROR_CODE();
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0;
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_int()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return p.get_int();
@ -447,12 +447,12 @@ extern "C" {
LOG_Z3_get_decl_double_parameter(c, d, idx);
RESET_ERROR_CODE();
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0;
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_double()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return p.get_double();
@ -464,12 +464,12 @@ extern "C" {
LOG_Z3_get_decl_symbol_parameter(c, d, idx);
RESET_ERROR_CODE();
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return nullptr;
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_symbol()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
return of_symbol(p.get_symbol());
@ -481,12 +481,12 @@ extern "C" {
LOG_Z3_get_decl_sort_parameter(c, d, idx);
RESET_ERROR_CODE();
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_ast() || !is_sort(p.get_ast())) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(of_sort(to_sort(p.get_ast())));
@ -498,12 +498,12 @@ extern "C" {
LOG_Z3_get_decl_ast_parameter(c, d, idx);
RESET_ERROR_CODE();
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_ast()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(of_ast(p.get_ast()));
@ -515,12 +515,12 @@ extern "C" {
LOG_Z3_get_decl_func_decl_parameter(c, d, idx);
RESET_ERROR_CODE();
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_ast() || !is_func_decl(p.get_ast())) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(of_func_decl(to_func_decl(p.get_ast())));
@ -532,12 +532,12 @@ extern "C" {
LOG_Z3_get_decl_rational_parameter(c, d, idx);
RESET_ERROR_CODE();
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return "";
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_rational()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return "";
}
return mk_c(c)->mk_external_string(p.get_rational().to_string());
@ -584,7 +584,7 @@ extern "C" {
LOG_Z3_get_domain(c, d, i);
RESET_ERROR_CODE();
if (i >= to_func_decl(d)->get_arity()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
Z3_sort r = of_sort(to_func_decl(d)->get_domain(i));
@ -740,7 +740,7 @@ extern "C" {
case AST_APP: {
app* e = to_app(a);
if (e->get_num_args() != num_args) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
}
else {
a = m.mk_app(e->get_decl(), num_args, args);
@ -749,7 +749,7 @@ extern "C" {
}
case AST_QUANTIFIER: {
if (num_args != 1) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
}
else {
a = m.update_quantifier(to_quantifier(a), args[0]);
@ -779,7 +779,7 @@ extern "C" {
expr * r = nullptr;
for (unsigned i = 0; i < num_exprs; i++) {
if (m.get_sort(from[i]) != m.get_sort(to[i])) {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(of_expr(nullptr));
}
SASSERT(from[i]->get_ref_count() > 0);
@ -808,8 +808,7 @@ extern "C" {
expr * a = to_expr(_a);
expr * const * to = to_exprs(_to);
var_subst subst(m, false);
expr_ref new_a(m);
subst(a, num_exprs, to, new_a);
expr_ref new_a = subst(a, num_exprs, to);
mk_c(c)->save_ast_trail(new_a);
RETURN_Z3(of_expr(new_a.get()));
Z3_CATCH_RETURN(nullptr);
@ -910,6 +909,7 @@ extern "C" {
case PR_TRANSITIVITY_STAR: return Z3_OP_PR_TRANSITIVITY_STAR;
case PR_MONOTONICITY: return Z3_OP_PR_MONOTONICITY;
case PR_QUANT_INTRO: return Z3_OP_PR_QUANT_INTRO;
case PR_BIND: return Z3_OP_PR_BIND;
case PR_DISTRIBUTIVITY: return Z3_OP_PR_DISTRIBUTIVITY;
case PR_AND_ELIM: return Z3_OP_PR_AND_ELIM;
case PR_NOT_OR_ELIM: return Z3_OP_PR_NOT_OR_ELIM;
@ -1212,14 +1212,14 @@ extern "C" {
RESET_ERROR_CODE();
ast* _a = reinterpret_cast<ast*>(a);
if (!_a || _a->get_kind() != AST_VAR) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
var* va = to_var(_a);
if (va) {
return va->get_idx();
}
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
Z3_CATCH_RETURN(0);
}
@ -1230,7 +1230,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_VALID_AST(a, nullptr);
if (c == target) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
SASSERT(mk_c(c)->m().contains(to_ast(a)));

View file

@ -71,7 +71,7 @@ extern "C" {
RESET_ERROR_CODE();
obj_map<ast, ast*>::obj_map_entry * entry = to_ast_map_ref(m).find_core(to_ast(k));
if (entry == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
else {

View file

@ -65,7 +65,7 @@ extern "C" {
LOG_Z3_ast_vector_get(c, v, i);
RESET_ERROR_CODE();
if (i >= to_ast_vector_ref(v).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
// Remark: Don't need to invoke save_object.
@ -79,7 +79,7 @@ extern "C" {
LOG_Z3_ast_vector_set(c, v, i, a);
RESET_ERROR_CODE();
if (i >= to_ast_vector_ref(v).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return;
}
to_ast_vector_ref(v).set(i, to_ast(a));
@ -107,8 +107,7 @@ extern "C" {
LOG_Z3_ast_vector_translate(c, v, t);
RESET_ERROR_CODE();
if (c == t) {
SET_ERROR_CODE(Z3_INVALID_ARG);
RETURN_Z3(nullptr);
RETURN_Z3(v);
}
ast_translation translator(mk_c(c)->m(), mk_c(t)->m());
Z3_ast_vector_ref * new_v = alloc(Z3_ast_vector_ref, *mk_c(t), mk_c(t)->m());

View file

@ -27,9 +27,6 @@ extern "C" {
Z3_TRY;
LOG_Z3_mk_bv_sort(c, sz);
RESET_ERROR_CODE();
if (sz == 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
}
parameter p(sz);
Z3_sort r = of_sort(mk_c(c)->m().mk_sort(mk_c(c)->get_bv_fid(), BV_SORT, 1, &p));
RETURN_Z3(r);
@ -163,7 +160,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
// Not logging this one, since it is just syntax sugar.
unsigned sz = Z3_get_bv_sort_size(c, s);
if (sz == 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "zero length bit-vector supplied");
return nullptr;
}
Z3_ast x = Z3_mk_int64(c, 1, s);
@ -393,7 +390,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
if (to_sort(t)->get_family_id() == mk_c(c)->get_bv_fid() && to_sort(t)->get_decl_kind() == BV_SORT) {
return to_sort(t)->get_parameter(0).get_int();
}
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "sort is not a bit-vector");
return 0;
Z3_CATCH_RETURN(0);
}

View file

@ -144,9 +144,11 @@ namespace api {
}
}
void context::set_error_code(Z3_error_code err) {
void context::set_error_code(Z3_error_code err, char const* opt_msg) {
m_error_code = err;
if (err != Z3_OK) {
m_exception_msg.clear();
if (opt_msg) m_exception_msg = opt_msg;
invoke_error_handler(err);
}
}
@ -159,7 +161,7 @@ namespace api {
void context::check_searching() {
if (m_searching) {
set_error_code(Z3_INVALID_USAGE); // TBD: error code could be fixed.
set_error_code(Z3_INVALID_USAGE, "cannot use function while searching"); // TBD: error code could be fixed.
}
}
@ -218,10 +220,9 @@ namespace api {
// Corner case bug: n may be in m_last_result, and this is the only reference to n.
// When, we execute reset() it is deleted
// To avoid this bug, I bump the reference counter before reseting m_last_result
m().inc_ref(n);
ast_ref node(n, m());
m_last_result.reset();
m_last_result.push_back(n);
m().dec_ref(n);
m_last_result.push_back(std::move(node));
}
else {
m_ast_trail.push_back(n);
@ -249,25 +250,24 @@ namespace api {
if (ex.has_error_code()) {
switch(ex.error_code()) {
case ERR_MEMOUT:
set_error_code(Z3_MEMOUT_FAIL);
set_error_code(Z3_MEMOUT_FAIL, nullptr);
break;
case ERR_PARSER:
set_error_code(Z3_PARSER_ERROR);
set_error_code(Z3_PARSER_ERROR, ex.msg());
break;
case ERR_INI_FILE:
set_error_code(Z3_INVALID_ARG);
set_error_code(Z3_INVALID_ARG, nullptr);
break;
case ERR_OPEN_FILE:
set_error_code(Z3_FILE_ACCESS_ERROR);
set_error_code(Z3_FILE_ACCESS_ERROR, nullptr);
break;
default:
set_error_code(Z3_INTERNAL_FATAL);
set_error_code(Z3_INTERNAL_FATAL, nullptr);
break;
}
}
else {
m_exception_msg = ex.msg();
set_error_code(Z3_EXCEPTION);
set_error_code(Z3_EXCEPTION, ex.msg());
}
}
@ -302,7 +302,7 @@ namespace api {
case AST_FUNC_DECL:
break;
}
set_error_code(Z3_SORT_ERROR);
set_error_code(Z3_SORT_ERROR, nullptr);
}
}
@ -380,7 +380,7 @@ extern "C" {
LOG_Z3_dec_ref(c, a);
RESET_ERROR_CODE();
if (to_ast(a)->get_ref_count() == 0) {
SET_ERROR_CODE(Z3_DEC_REF_ERROR);
SET_ERROR_CODE(Z3_DEC_REF_ERROR, nullptr);
return;
}
mk_c(c)->m().dec_ref(to_ast(a));
@ -441,10 +441,14 @@ extern "C" {
}
void Z3_API Z3_set_error(Z3_context c, Z3_error_code e) {
SET_ERROR_CODE(e);
SET_ERROR_CODE(e, nullptr);
}
static char const * _get_error_msg(Z3_context c, Z3_error_code err) {
if (c) {
char const* msg = mk_c(c)->get_exception_msg();
if (msg && *msg) return msg;
}
switch(err) {
case Z3_OK: return "ok";
case Z3_SORT_ERROR: return "type error";
@ -458,7 +462,7 @@ extern "C" {
case Z3_INTERNAL_FATAL: return "internal error";
case Z3_INVALID_USAGE: return "invalid usage";
case Z3_DEC_REF_ERROR: return "invalid dec_ref command";
case Z3_EXCEPTION: return c == nullptr ? "Z3 exception" : mk_c(c)->get_exception_msg();
case Z3_EXCEPTION: return "Z3 exception";
default: return "unknown";
}
}

View file

@ -141,7 +141,7 @@ namespace api {
Z3_error_code get_error_code() const { return m_error_code; }
void reset_error_code();
void set_error_code(Z3_error_code err);
void set_error_code(Z3_error_code err, char const* opt_msg);
void set_error_handler(Z3_error_handler h) { m_error_handler = h; }
// Sign an error if solver is searching
void check_searching();
@ -219,14 +219,6 @@ namespace api {
//
// ------------------------
smt_params & fparams() { return m_fparams; }
// ------------------------
//
// Parser interface
//
// ------------------------
std::string m_parser_error_buffer;
};
@ -234,14 +226,14 @@ namespace api {
inline api::context * mk_c(Z3_context c) { return reinterpret_cast<api::context*>(c); }
#define RESET_ERROR_CODE() { mk_c(c)->reset_error_code(); }
#define SET_ERROR_CODE(ERR) { mk_c(c)->set_error_code(ERR); }
#define CHECK_NON_NULL(_p_,_ret_) { if (_p_ == 0) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
#define CHECK_VALID_AST(_a_, _ret_) { if (_a_ == 0 || !CHECK_REF_COUNT(_a_)) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
#define SET_ERROR_CODE(ERR, MSG) { mk_c(c)->set_error_code(ERR, MSG); }
#define CHECK_NON_NULL(_p_,_ret_) { if (_p_ == 0) { SET_ERROR_CODE(Z3_INVALID_ARG, "ast is null"); return _ret_; } }
#define CHECK_VALID_AST(_a_, _ret_) { if (_a_ == 0 || !CHECK_REF_COUNT(_a_)) { SET_ERROR_CODE(Z3_INVALID_ARG, "not a valid ast"); return _ret_; } }
#define CHECK_SEARCHING(c) mk_c(c)->check_searching();
inline bool is_expr(Z3_ast a) { return is_expr(to_ast(a)); }
#define CHECK_IS_EXPR(_p_, _ret_) { if (_p_ == 0 || !is_expr(_p_)) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
#define CHECK_IS_EXPR(_p_, _ret_) { if (_p_ == 0 || !is_expr(_p_)) { SET_ERROR_CODE(Z3_INVALID_ARG, "ast is not an expression"); return _ret_; } }
inline bool is_bool_expr(Z3_context c, Z3_ast a) { return is_expr(a) && mk_c(c)->m().is_bool(to_expr(a)); }
#define CHECK_FORMULA(_a_, _ret_) { if (_a_ == 0 || !CHECK_REF_COUNT(_a_) || !is_bool_expr(c, _a_)) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
#define CHECK_FORMULA(_a_, _ret_) { if (_a_ == 0 || !CHECK_REF_COUNT(_a_) || !is_bool_expr(c, _a_)) { SET_ERROR_CODE(Z3_INVALID_ARG, nullptr); return _ret_; } }
inline void check_sorts(Z3_context c, ast * n) { mk_c(c)->check_sorts(n); }
#endif

View file

@ -157,7 +157,7 @@ extern "C" {
RESET_ERROR_CODE();
sort * r = to_sort(s);
if (Z3_get_sort_kind(c, s) != Z3_RELATION_SORT) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "sort should be a relation");
return 0;
}
return r->get_num_parameters();
@ -170,18 +170,18 @@ extern "C" {
RESET_ERROR_CODE();
sort * r = to_sort(s);
if (Z3_get_sort_kind(c, s) != Z3_RELATION_SORT) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "sort should be a relation");
RETURN_Z3(nullptr);
}
if (col >= r->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
parameter const& p = r->get_parameter(col);
if (!p.is_ast() || !is_sort(p.get_ast())) {
UNREACHABLE();
warning_msg("Sort parameter expected at %d", col);
SET_ERROR_CODE(Z3_INTERNAL_FATAL);
SET_ERROR_CODE(Z3_INTERNAL_FATAL, "sort parameter expected");
RETURN_Z3(nullptr);
}
Z3_sort res = of_sort(to_sort(p.get_ast()));
@ -364,7 +364,7 @@ extern "C" {
install_dl_collect_cmds(coll, ctx);
ctx.set_ignore_check(true);
if (!parse_smt2_commands(ctx, s)) {
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, nullptr);
return nullptr;
}
@ -408,7 +408,7 @@ extern "C" {
LOG_Z3_fixedpoint_from_file(c, d, s);
std::ifstream is(s);
if (!is) {
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(Z3_fixedpoint_from_stream(c, d, is));

View file

@ -56,7 +56,7 @@ extern "C" {
del_datatype_decl(dt);
if (!is_ok) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -118,7 +118,7 @@ extern "C" {
del_datatype_decl(dt);
if (!is_ok) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -180,7 +180,7 @@ extern "C" {
del_datatype_decl(decl);
if (!is_ok) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -274,7 +274,7 @@ extern "C" {
RESET_ERROR_CODE();
mk_c(c)->reset_last_result();
if (!constr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return;
}
ast_manager& m = mk_c(c)->m();
@ -282,7 +282,7 @@ extern "C" {
func_decl* f = reinterpret_cast<constructor*>(constr)->m_constructor.get();
if (!f) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return;
}
if (constructor_decl) {
@ -353,7 +353,7 @@ extern "C" {
del_datatype_decl(data);
if (!is_ok) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -416,7 +416,7 @@ extern "C" {
del_datatype_decls(datas.size(), datas.c_ptr());
if (!ok) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return;
}
@ -445,7 +445,7 @@ extern "C" {
datatype_util& dt_util = mk_c(c)->dtutil();
if (!dt_util.is_datatype(_t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return dt_util.get_datatype_constructors(_t)->size();
@ -458,12 +458,12 @@ extern "C" {
sort * _t = to_sort(t);
datatype_util& dt_util = mk_c(c)->dtutil();
if (!dt_util.is_datatype(_t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(_t);
if (idx >= decls.size()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
func_decl* decl = (decls)[idx];
@ -488,12 +488,12 @@ extern "C" {
datatype_util& dt_util = mk_c(c)->dtutil();
if (!dt_util.is_datatype(_t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(_t);
if (idx >= decls.size()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
func_decl* decl = (decls)[idx];
@ -511,23 +511,23 @@ extern "C" {
datatype_util& dt_util = mk_c(c)->dtutil();
if (!dt_util.is_datatype(_t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(_t);
if (idx_c >= decls.size()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
func_decl* decl = (decls)[idx_c];
if (decl->get_arity() <= idx_a) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<func_decl> const & accs = *dt_util.get_constructor_accessors(decl);
SASSERT(accs.size() == decl->get_arity());
if (accs.size() <= idx_a) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
decl = (accs)[idx_a];
@ -543,7 +543,7 @@ extern "C" {
sort * tuple = to_sort(t);
datatype_util& dt_util = mk_c(c)->dtutil();
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
Z3_func_decl r = get_datatype_sort_constructor_core(c, t, 0);
@ -558,12 +558,12 @@ extern "C" {
sort * tuple = to_sort(t);
datatype_util& dt_util = mk_c(c)->dtutil();
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(tuple);
if (decls.size() != 1) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
ptr_vector<func_decl> const & accs = *dt_util.get_constructor_accessors(decls[0]);
@ -578,17 +578,17 @@ extern "C" {
sort * tuple = to_sort(t);
datatype_util& dt_util = mk_c(c)->dtutil();
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(tuple);
if (decls.size() != 1) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<func_decl> const & accs = *dt_util.get_constructor_accessors((decls)[0]);
if (accs.size() <= i) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
func_decl* acc = (accs)[i];

View file

@ -175,7 +175,7 @@ extern "C" {
LOG_Z3_mk_fpa_sort(c, ebits, sbits);
RESET_ERROR_CODE();
if (ebits < 2 || sbits < 3) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "ebits should be at least 2, sbits at least 3");
}
api::context * ctx = mk_c(c);
sort * s = ctx->fpautil().mk_float_sort(ebits, sbits);
@ -222,7 +222,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_VALID_AST(s, nullptr);
if (!is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -238,7 +238,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_VALID_AST(s, nullptr);
if (!is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -255,7 +255,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_VALID_AST(s, nullptr);
if (!is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -271,7 +271,7 @@ extern "C" {
LOG_Z3_mk_fpa_fp(c, sgn, exp, sig);
RESET_ERROR_CODE();
if (!is_bv(c, sgn) || !is_bv(c, exp) || !is_bv(c, sig)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "bv sorts expected for arguments");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -286,7 +286,7 @@ extern "C" {
LOG_Z3_mk_fpa_numeral_float(c, v, ty);
RESET_ERROR_CODE();
if (!is_fp_sort(c, ty)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG,"fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -306,7 +306,7 @@ extern "C" {
LOG_Z3_mk_fpa_numeral_double(c, v, ty);
RESET_ERROR_CODE();
if (!is_fp_sort(c, ty)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -323,7 +323,7 @@ extern "C" {
LOG_Z3_mk_fpa_numeral_int(c, v, ty);
RESET_ERROR_CODE();
if (!is_fp_sort(c, ty)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -343,7 +343,7 @@ extern "C" {
LOG_Z3_mk_fpa_numeral_int64_uint64(c, sgn, exp, sig, ty);
RESET_ERROR_CODE();
if (!is_fp_sort(c, ty)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -363,7 +363,7 @@ extern "C" {
LOG_Z3_mk_fpa_numeral_int64_uint64(c, sgn, exp, sig, ty);
RESET_ERROR_CODE();
if (!is_fp_sort(c, ty)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -383,7 +383,7 @@ extern "C" {
LOG_Z3_mk_fpa_abs(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -398,7 +398,7 @@ extern "C" {
LOG_Z3_mk_fpa_neg(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -413,7 +413,7 @@ extern "C" {
LOG_Z3_mk_fpa_add(c, rm, t1, t2);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -428,7 +428,7 @@ extern "C" {
LOG_Z3_mk_fpa_add(c, rm, t1, t2);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -443,7 +443,7 @@ extern "C" {
LOG_Z3_mk_fpa_add(c, rm, t1, t2);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -458,7 +458,7 @@ extern "C" {
LOG_Z3_mk_fpa_add(c, rm, t1, t2);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -473,7 +473,7 @@ extern "C" {
LOG_Z3_mk_fpa_fma(c, rm, t1, t2, t3);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t1) || !is_fp(c, t2) || !is_fp(c, t3)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -488,7 +488,7 @@ extern "C" {
LOG_Z3_mk_fpa_sqrt(c, rm, t);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -503,7 +503,7 @@ extern "C" {
LOG_Z3_mk_fpa_rem(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -518,7 +518,7 @@ extern "C" {
LOG_Z3_mk_fpa_round_to_integral(c, rm, t);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -533,7 +533,7 @@ extern "C" {
LOG_Z3_mk_fpa_min(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -548,7 +548,7 @@ extern "C" {
LOG_Z3_mk_fpa_max(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -563,7 +563,7 @@ extern "C" {
LOG_Z3_mk_fpa_leq(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -578,7 +578,7 @@ extern "C" {
LOG_Z3_mk_fpa_lt(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -593,7 +593,7 @@ extern "C" {
LOG_Z3_mk_fpa_geq(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -608,7 +608,7 @@ extern "C" {
LOG_Z3_mk_fpa_gt(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -623,7 +623,7 @@ extern "C" {
LOG_Z3_mk_fpa_eq(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -638,7 +638,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_normal(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -653,7 +653,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_subnormal(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -668,7 +668,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_zero(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -683,7 +683,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_infinite(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -698,7 +698,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_nan(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -713,7 +713,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_negative(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -728,7 +728,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_positive(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -744,14 +744,14 @@ extern "C" {
LOG_Z3_mk_fpa_to_fp_bv(c, bv, s);
RESET_ERROR_CODE();
if (!is_bv(c, bv) || !is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "bv then fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!ctx->bvutil().is_bv(to_expr(bv)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "bv sort the flaot sort expected");
return nullptr;
}
expr * a = fu.mk_to_fp(to_sort(s), to_expr(bv));
@ -769,7 +769,7 @@ extern "C" {
if (!fu.is_rm(to_expr(rm)) ||
!fu.is_float(to_expr(t)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
return nullptr;
}
expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t));
@ -787,7 +787,7 @@ extern "C" {
if (!fu.is_rm(to_expr(rm)) ||
!ctx->autil().is_real(to_expr(t)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
return nullptr;
}
expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t));
@ -805,7 +805,7 @@ extern "C" {
if (!fu.is_rm(to_expr(rm)) ||
!ctx->bvutil().is_bv(to_expr(t)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
return nullptr;
}
expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t));
@ -823,7 +823,7 @@ extern "C" {
if (!fu.is_rm(to_expr(rm)) ||
!ctx->bvutil().is_bv(to_expr(t)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
return nullptr;
}
expr * a = fu.mk_to_fp_unsigned(to_sort(s), to_expr(rm), to_expr(t));
@ -837,7 +837,7 @@ extern "C" {
LOG_Z3_mk_fpa_to_ubv(c, rm, t, sz);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -852,7 +852,7 @@ extern "C" {
LOG_Z3_mk_fpa_to_sbv(c, rm, t, sz);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -867,7 +867,7 @@ extern "C" {
LOG_Z3_mk_fpa_to_real(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -884,7 +884,7 @@ extern "C" {
CHECK_NON_NULL(s, 0);
CHECK_VALID_AST(s, 0);
if (!is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(0);
}
return mk_c(c)->fpautil().get_ebits(to_sort(s));
@ -898,7 +898,7 @@ extern "C" {
CHECK_NON_NULL(s, 0);
CHECK_VALID_AST(s, 0);
if (!is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(0);
}
return mk_c(c)->fpautil().get_sbits(to_sort(s));
@ -912,7 +912,7 @@ extern "C" {
CHECK_NON_NULL(t, 0);
CHECK_VALID_AST(t, 0);
if (sgn == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "sign cannot be a nullpointer");
return 0;
}
ast_manager & m = mk_c(c)->m();
@ -921,13 +921,13 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
return 0;
}
*sgn = mpfm.sgn(val);
@ -948,13 +948,13 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
return nullptr;
}
app * a;
@ -981,13 +981,13 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
RETURN_Z3(nullptr);
}
unsigned sbits = val.get().get_sbits();
@ -1014,13 +1014,13 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
return "";
}
unsigned sbits = val.get().get_sbits();
@ -1042,7 +1042,7 @@ extern "C" {
CHECK_NON_NULL(t, 0);
CHECK_VALID_AST(t, 0);
if (n == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid nullptr argument");
return 0;
}
ast_manager & m = mk_c(c)->m();
@ -1053,7 +1053,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
*n = 0;
return 0;
}
@ -1063,7 +1063,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
*n = 0;
return 0;
}
@ -1085,13 +1085,13 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
return "";
}
unsigned ebits = val.get().get_ebits();
@ -1120,7 +1120,7 @@ extern "C" {
CHECK_NON_NULL(t, 0);
CHECK_VALID_AST(t, 0);
if (n == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid null argument");
return 0;
}
ast_manager & m = mk_c(c)->m();
@ -1130,14 +1130,14 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
*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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
*n = 0;
return 0;
}
@ -1169,13 +1169,13 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
RETURN_Z3(nullptr);
}
unsigned ebits = val.get().get_ebits();
@ -1204,7 +1204,7 @@ extern "C" {
CHECK_NON_NULL(t, nullptr);
CHECK_VALID_AST(t, nullptr);
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -1223,7 +1223,7 @@ extern "C" {
!ctx->autil().is_int(to_expr(exp)) ||
!ctx->autil().is_real(to_expr(sig)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(exp), to_expr(sig));
@ -1239,7 +1239,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_nan(to_expr(t));
@ -1253,7 +1253,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_inf(to_expr(t));
@ -1267,7 +1267,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_zero(to_expr(t));
@ -1281,7 +1281,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_normal(to_expr(t));
@ -1295,7 +1295,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_subnormal(to_expr(t));
@ -1309,7 +1309,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_positive(to_expr(t));
@ -1323,7 +1323,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_negative(to_expr(t));

View file

@ -30,7 +30,7 @@ extern "C" {
LOG_Z3_mk_goal(c, models, unsat_cores, proofs);
RESET_ERROR_CODE();
if (proofs != 0 && !mk_c(c)->m().proofs_enabled()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "proofs are required, but proofs are not enabled on the context");
RETURN_Z3(nullptr);
}
Z3_goal_ref * g = alloc(Z3_goal_ref, *mk_c(c));
@ -119,7 +119,7 @@ extern "C" {
LOG_Z3_goal_formula(c, g, idx);
RESET_ERROR_CODE();
if (idx >= to_goal_ref(g)->size()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
expr * result = to_goal_ref(g)->form(idx);
@ -198,6 +198,10 @@ extern "C" {
LOG_Z3_goal_to_dimacs_string(c, g);
RESET_ERROR_CODE();
std::ostringstream buffer;
if (!to_goal_ref(g)->is_cnf()) {
SET_ERROR_CODE(Z3_INVALID_ARG, "If this is not what you want, then preprocess by optional bit-blasting and applying tseitin-cnf");
RETURN_Z3(nullptr);
}
to_goal_ref(g)->display_dimacs(buffer);
// Hack for removing the trailing '\n'
std::string result = buffer.str();

View file

@ -94,7 +94,7 @@ extern "C" {
CHECK_NON_NULL(m, nullptr);
func_interp * _fi = to_model_ref(m)->get_func_interp(to_func_decl(f));
if (!_fi) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
Z3_func_interp_ref * fi = alloc(Z3_func_interp_ref, *mk_c(c), to_model_ref(m));
@ -123,7 +123,7 @@ extern "C" {
RETURN_Z3(of_func_decl(_m->get_constant(i)));
}
else {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -142,7 +142,7 @@ extern "C" {
CHECK_NON_NULL(m, nullptr);
model * _m = to_model_ref(m);
if (i >= _m->get_num_functions()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return nullptr;
}
return of_func_decl(_m->get_function(i));
@ -187,7 +187,7 @@ extern "C" {
LOG_Z3_model_get_sort(c, m, i);
RESET_ERROR_CODE();
if (i >= to_model_ref(m)->get_num_uninterpreted_sorts()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
sort * s = to_model_ref(m)->get_uninterpreted_sort(i);
@ -200,7 +200,7 @@ extern "C" {
LOG_Z3_model_get_sort_universe(c, m, s);
RESET_ERROR_CODE();
if (!to_model_ref(m)->has_uninterpreted_sort(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<expr> const & universe = to_model_ref(m)->get_universe(to_sort(s));
@ -242,7 +242,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -269,7 +269,7 @@ extern "C" {
RESET_ERROR_CODE();
func_decl* d = to_func_decl(f);
if (d->get_arity() != 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
}
else {
model* mdl = to_model_ref(m);
@ -313,7 +313,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_NON_NULL(f, nullptr);
if (i >= to_func_interp_ref(f)->num_entries()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
Z3_func_entry_ref * e = alloc(Z3_func_entry_ref, *mk_c(c), to_func_interp(f)->m_model.get());
@ -364,7 +364,7 @@ extern "C" {
func_interp* _fi = to_func_interp_ref(fi);
expr* _value = to_expr(value);
if (to_ast_vector_ref(args).size() != _fi->get_arity()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return;
}
// check sorts of value
@ -416,7 +416,7 @@ extern "C" {
LOG_Z3_func_entry_get_arg(c, e, i);
RESET_ERROR_CODE();
if (i >= to_func_entry(e)->m_func_interp->get_arity()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
expr * r = to_func_entry(e)->m_func_entry->get_arg(i);
@ -434,7 +434,7 @@ extern "C" {
if (g) {
return g->num_entries();
}
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0;
}
return 0;
@ -448,7 +448,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_NON_NULL(m, 0);
if (j >= get_model_func_num_entries_core(c, m, i)) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0;
}
Z3_func_decl d = get_model_func_decl_core(c, m, i);

View file

@ -40,7 +40,7 @@ bool is_numeral_sort(Z3_context c, Z3_sort ty) {
bool check_numeral_sort(Z3_context c, Z3_sort ty) {
bool is_num = is_numeral_sort(c, ty);
if (!is_num) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
}
return is_num;
}
@ -55,7 +55,7 @@ extern "C" {
RETURN_Z3(nullptr);
}
if (!n) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
sort * _ty = to_sort(ty);
@ -72,7 +72,7 @@ extern "C" {
(('p' == *m) ||
('P' == *m) ||
('+' == *m))))) {
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, nullptr);
RETURN_Z3(nullptr);
}
++m;
@ -162,7 +162,7 @@ extern "C" {
RESET_ERROR_CODE();
expr* e = to_expr(a);
if (!e) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
}
if (mk_c(c)->autil().is_numeral(e, r)) {
@ -221,7 +221,7 @@ extern "C" {
return mk_c(c)->mk_external_string(fu.fm().to_string(tmp));
}
else {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return "";
}
}
@ -234,7 +234,7 @@ extern "C" {
RESET_ERROR_CODE();
expr* e = to_expr(a);
if (!e) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return "";
}
rational r;
@ -256,7 +256,7 @@ extern "C" {
return mk_c(c)->mk_external_string(r.to_string());
}
else {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return "";
}
Z3_CATCH_RETURN("");
@ -281,7 +281,7 @@ extern "C" {
return Z3_FALSE;
}
}
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
Z3_CATCH_RETURN(Z3_FALSE);
}
@ -293,7 +293,7 @@ extern "C" {
LOG_Z3_get_numeral_int(c, v, i);
RESET_ERROR_CODE();
if (!i) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
}
int64_t l;
@ -311,7 +311,7 @@ extern "C" {
LOG_Z3_get_numeral_uint(c, v, u);
RESET_ERROR_CODE();
if (!u) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
}
uint64_t l;
@ -329,7 +329,7 @@ extern "C" {
LOG_Z3_get_numeral_uint64(c, v, u);
RESET_ERROR_CODE();
if (!u) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
}
rational r;
@ -349,7 +349,7 @@ extern "C" {
LOG_Z3_get_numeral_int64(c, v, i);
RESET_ERROR_CODE();
if (!i) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
}
rational r;
@ -368,7 +368,7 @@ extern "C" {
LOG_Z3_get_numeral_rational_int64(c, v, num, den);
RESET_ERROR_CODE();
if (!num || !den) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
}
rational r;

View file

@ -173,6 +173,7 @@ extern "C" {
to_optimize_ptr(o)->get_model(_m);
Z3_model_ref * m_ref = alloc(Z3_model_ref, *mk_c(c));
if (_m) {
if (mk_c(c)->params().m_model_compress) _m->compress();
m_ref->m_model = _m;
}
else {
@ -317,17 +318,15 @@ extern "C" {
ctx->set_ignore_check(true);
try {
if (!parse_smt2_commands(*ctx.get(), s)) {
mk_c(c)->m_parser_error_buffer = errstrm.str();
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, errstrm.str().c_str());
return;
}
}
catch (z3_exception& e) {
errstrm << e.msg();
mk_c(c)->m_parser_error_buffer = errstrm.str();
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, errstrm.str().c_str());
return;
}

View file

@ -171,7 +171,7 @@ extern "C" {
LOG_Z3_param_descrs_get_name(c, p, i);
RESET_ERROR_CODE();
if (i >= to_param_descrs_ptr(p)->size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
Z3_symbol result = of_symbol(to_param_descrs_ptr(p)->get_param_name(i));
@ -185,7 +185,7 @@ extern "C" {
RESET_ERROR_CODE();
char const* result = to_param_descrs_ptr(p)->get_descr(to_symbol(s));
if (result == nullptr) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
return mk_c(c)->mk_external_string(result);

View file

@ -30,15 +30,6 @@ Revision History:
extern "C" {
Z3_string Z3_API Z3_get_parser_error(Z3_context c) {
Z3_TRY;
LOG_Z3_get_parser_error(c);
RESET_ERROR_CODE();
return mk_c(c)->m_parser_error_buffer.c_str();
Z3_CATCH_RETURN("");
}
// ---------------
// Support for SMTLIB2
@ -70,16 +61,14 @@ extern "C" {
try {
if (!parse_smt2_commands(*ctx.get(), is)) {
ctx = nullptr;
mk_c(c)->m_parser_error_buffer = errstrm.str();
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, errstrm.str().c_str());
return of_ast_vector(v);
}
}
catch (z3_exception& e) {
errstrm << e.msg();
mk_c(c)->m_parser_error_buffer = errstrm.str();
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, errstrm.str().c_str());
return of_ast_vector(v);
}
ptr_vector<expr>::const_iterator it = ctx->begin_assertions();
@ -118,7 +107,7 @@ extern "C" {
LOG_Z3_parse_smtlib2_string(c, file_name, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
std::ifstream is(file_name);
if (!is) {
SET_ERROR_CODE(Z3_FILE_ACCESS_ERROR);
SET_ERROR_CODE(Z3_FILE_ACCESS_ERROR, nullptr);
return nullptr;
}
Z3_ast_vector r = parse_smtlib2_stream(false, c, is, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
@ -141,15 +130,13 @@ extern "C" {
ctx->set_diagnostic_stream(ous);
try {
if (!parse_smt2_commands(*ctx.get(), is)) {
mk_c(c)->m_parser_error_buffer = ous.str();
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, ous.str().c_str());
RETURN_Z3(mk_c(c)->mk_external_string(ous.str()));
}
}
catch (z3_exception& e) {
if (ous.str().empty()) ous << e.msg();
mk_c(c)->m_parser_error_buffer = ous.str();
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, ous.str().c_str());
RETURN_Z3(mk_c(c)->mk_external_string(ous.str()));
}
RETURN_Z3(mk_c(c)->mk_external_string(ous.str()));

View file

@ -49,7 +49,7 @@ extern "C" {
default_expr2polynomial converter(mk_c(c)->m(), pm);
if (!converter.to_polynomial(to_expr(p), _p, d) ||
!converter.to_polynomial(to_expr(q), _q, d)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
Z3_ast_vector_ref* result = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());

View file

@ -55,7 +55,7 @@ extern "C"
app_ref_vector vars(mk_c(c)->m ());
if (!to_apps(num_bounds, bound, vars)) {
SET_ERROR_CODE (Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
@ -141,7 +141,7 @@ extern "C"
for (unsigned i = 0; i < vVars.size (); ++i) {
app *a = to_app (vVars.get (i));
if (a->get_kind () != AST_APP) {
SET_ERROR_CODE (Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
vApps.push_back (a);

View file

@ -62,11 +62,11 @@ extern "C" {
Z3_TRY;
RESET_ERROR_CODE();
if (!mk_c(c)->m().is_bool(to_expr(body))) {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return nullptr;
}
if (num_patterns > 0 && num_no_patterns > 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, nullptr);
return nullptr;
}
expr * const* ps = reinterpret_cast<expr * const*>(patterns);
@ -77,7 +77,7 @@ extern "C" {
pattern_validator v(mk_c(c)->m());
for (unsigned i = 0; i < num_patterns; i++) {
if (!v(num_decls, ps[i], 0, 0)) {
SET_ERROR_CODE(Z3_INVALID_PATTERN);
SET_ERROR_CODE(Z3_INVALID_PATTERN, nullptr);
return nullptr;
}
}
@ -90,7 +90,7 @@ extern "C" {
expr_ref result(mk_c(c)->m());
if (num_decls > 0) {
result = mk_c(c)->m().mk_quantifier(
(0 != is_forall),
is_forall ? forall_k : exists_k,
names.size(), ts, names.c_ptr(), to_expr(body),
weight,
qid,
@ -144,6 +144,61 @@ extern "C" {
return Z3_mk_quantifier(c, 0, weight, num_patterns, patterns, num_decls, types, decl_names, body);
}
Z3_ast Z3_API Z3_mk_lambda(Z3_context c,
unsigned num_decls, Z3_sort const types[],
Z3_symbol const decl_names[],
Z3_ast body) {
Z3_TRY;
LOG_Z3_mk_lambda(c, num_decls, types, decl_names, body);
RESET_ERROR_CODE();
expr_ref result(mk_c(c)->m());
if (num_decls == 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE, nullptr);
RETURN_Z3(0);
}
sort* const* ts = reinterpret_cast<sort * const*>(types);
svector<symbol> names;
for (unsigned i = 0; i < num_decls; ++i) {
names.push_back(to_symbol(decl_names[i]));
}
result = mk_c(c)->m().mk_lambda(names.size(), ts, names.c_ptr(), to_expr(body));
mk_c(c)->save_ast_trail(result.get());
return of_ast(result.get());
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_mk_lambda_const(Z3_context c,
unsigned num_decls, Z3_app const vars[],
Z3_ast body) {
Z3_TRY;
LOG_Z3_mk_lambda_const(c, num_decls, vars, body);
RESET_ERROR_CODE();
if (num_decls == 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE, nullptr);
RETURN_Z3(0);
}
svector<symbol> _names;
ptr_vector<sort> _vars;
ptr_vector<expr> _args;
for (unsigned i = 0; i < num_decls; ++i) {
app* a = to_app(vars[i]);
_names.push_back(to_app(a)->get_decl()->get_name());
_args.push_back(a);
_vars.push_back(mk_c(c)->m().get_sort(a));
}
expr_ref result(mk_c(c)->m());
expr_abstract(mk_c(c)->m(), 0, num_decls, _args.c_ptr(), to_expr(body), result);
result = mk_c(c)->m().mk_lambda(_vars.size(), _vars.c_ptr(), _names.c_ptr(), result);
mk_c(c)->save_ast_trail(result.get());
return of_ast(result.get());
Z3_CATCH_RETURN(0);
}
Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c,
Z3_bool is_forall,
@ -165,17 +220,17 @@ extern "C" {
svector<Z3_sort> types;
ptr_vector<expr> bound_asts;
if (num_patterns > 0 && num_no_patterns > 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, nullptr);
RETURN_Z3(nullptr);
}
if (num_bound == 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "number of bound variables is 0");
RETURN_Z3(nullptr);
}
for (unsigned i = 0; i < num_bound; ++i) {
app* a = to_app(bound[i]);
if (a->get_kind() != AST_APP) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
symbol s(to_app(a)->get_decl()->get_name());
@ -183,7 +238,7 @@ extern "C" {
types.push_back(of_sort(mk_c(c)->m().get_sort(a)));
bound_asts.push_back(a);
if (a->get_family_id() != null_family_id || a->get_num_args() != 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -204,7 +259,7 @@ extern "C" {
for (unsigned i = 0; i < num_no_patterns; ++i) {
expr_ref result(mk_c(c)->m());
if (!is_app(to_expr(no_patterns[i]))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
app* pat = to_app(to_expr(no_patterns[i]));
@ -268,7 +323,7 @@ extern "C" {
RESET_ERROR_CODE();
for (unsigned i = 0; i < num_patterns; ++i) {
if (!is_app(to_expr(terms[i]))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -292,17 +347,27 @@ extern "C" {
Z3_TRY;
LOG_Z3_is_quantifier_forall(c, a);
RESET_ERROR_CODE();
ast * _a = to_ast(a);
if (_a->get_kind() == AST_QUANTIFIER) {
return to_quantifier(_a)->is_forall();
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
return Z3_FALSE;
}
return ::is_forall(to_ast(a)) ? Z3_TRUE : Z3_FALSE;
Z3_CATCH_RETURN(Z3_FALSE);
}
Z3_bool Z3_API Z3_is_quantifier_exists(Z3_context c, Z3_ast a) {
Z3_TRY;
LOG_Z3_is_quantifier_exists(c, a);
RESET_ERROR_CODE();
return ::is_exists(to_ast(a)) ? Z3_TRUE : Z3_FALSE;
Z3_CATCH_RETURN(Z3_FALSE);
}
Z3_bool Z3_API Z3_is_lambda(Z3_context c, Z3_ast a) {
Z3_TRY;
LOG_Z3_is_lambda(c, a);
RESET_ERROR_CODE();
return ::is_lambda(to_ast(a)) ? Z3_TRUE : Z3_FALSE;
Z3_CATCH_RETURN(Z3_FALSE);
}
unsigned Z3_API Z3_get_quantifier_weight(Z3_context c, Z3_ast a) {
Z3_TRY;
LOG_Z3_get_quantifier_weight(c, a);
@ -312,7 +377,7 @@ extern "C" {
return to_quantifier(_a)->get_weight();
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return 0;
}
Z3_CATCH_RETURN(0);
@ -327,7 +392,7 @@ extern "C" {
return to_quantifier(_a)->get_num_patterns();
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return 0;
}
Z3_CATCH_RETURN(0);
@ -343,7 +408,7 @@ extern "C" {
RETURN_Z3(r);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -359,7 +424,7 @@ extern "C" {
return to_quantifier(_a)->get_num_no_patterns();
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return 0;
}
Z3_CATCH_RETURN(0);
@ -375,7 +440,7 @@ extern "C" {
RETURN_Z3(r);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -390,7 +455,7 @@ extern "C" {
return of_symbol(to_quantifier(_a)->get_decl_names()[i]);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return nullptr;
}
Z3_CATCH_RETURN(nullptr);
@ -406,7 +471,7 @@ extern "C" {
RETURN_Z3(r);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -422,7 +487,7 @@ extern "C" {
RETURN_Z3(r);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -438,7 +503,7 @@ extern "C" {
return to_quantifier(_a)->get_num_decls();
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return 0;
}
Z3_CATCH_RETURN(0);
@ -453,7 +518,7 @@ extern "C" {
return _p->get_num_args();
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return 0;
}
Z3_CATCH_RETURN(0);
@ -469,7 +534,7 @@ extern "C" {
RETURN_Z3(r);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -485,3 +550,4 @@ extern "C" {
}
};

View file

@ -123,7 +123,7 @@ extern "C" {
}
if (rz == 0) {
// it is the zero polynomial
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
av.shrink(rz);

View file

@ -107,7 +107,7 @@ extern "C" {
RESET_ERROR_CODE();
zstring str;
if (!mk_c(c)->sutil().str.is_string(to_expr(s), str)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "expression is not a string literal");
return "";
}
std::string result = str.encode();

View file

@ -145,10 +145,12 @@ extern "C" {
void solver_from_stream(Z3_context c, Z3_solver s, std::istream& is) {
scoped_ptr<cmd_context> ctx = alloc(cmd_context, false, &(mk_c(c)->m()));
ctx->set_ignore_check(true);
std::stringstream errstrm;
ctx->set_regular_stream(errstrm);
if (!parse_smt2_commands(*ctx.get(), is)) {
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, errstrm.str().c_str());
return;
}
@ -178,7 +180,7 @@ extern "C" {
char const* ext = get_extension(file_name);
std::ifstream is(file_name);
if (!is) {
SET_ERROR_CODE(Z3_FILE_ACCESS_ERROR);
SET_ERROR_CODE(Z3_FILE_ACCESS_ERROR, nullptr);
}
else if (ext && std::string("dimacs") == ext) {
ast_manager& m = to_solver_ref(s)->get_manager();
@ -291,7 +293,7 @@ extern "C" {
RESET_ERROR_CODE();
init_solver(c, s);
if (n > to_solver_ref(s)->get_scope_level()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return;
}
if (n > 0)
@ -372,7 +374,7 @@ extern "C" {
static Z3_lbool _solver_check(Z3_context c, Z3_solver s, unsigned num_assumptions, Z3_ast const assumptions[]) {
for (unsigned i = 0; i < num_assumptions; i++) {
if (!is_expr(to_ast(assumptions[i]))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "assumption is not an expression");
return Z3_L_UNDEF;
}
}
@ -430,9 +432,12 @@ extern "C" {
model_ref _m;
to_solver_ref(s)->get_model(_m);
if (!_m) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "there is no current model");
RETURN_Z3(nullptr);
}
if (_m) {
if (mk_c(c)->params().m_model_compress) _m->compress();
}
Z3_model_ref * m_ref = alloc(Z3_model_ref, *mk_c(c));
m_ref->m_model = _m;
mk_c(c)->save_object(m_ref);
@ -447,7 +452,7 @@ extern "C" {
init_solver(c, s);
proof * p = to_solver_ref(s)->get_proof();
if (!p) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "there is no current proof");
RETURN_Z3(nullptr);
}
mk_c(c)->save_ast_trail(p);
@ -539,7 +544,7 @@ extern "C" {
for (ast* e : __assumptions) {
if (!is_expr(e)) {
_assumptions.finalize(); _consequences.finalize(); _variables.finalize();
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "assumption is not an expression");
return Z3_L_UNDEF;
}
_assumptions.push_back(to_expr(e));
@ -548,7 +553,7 @@ extern "C" {
for (ast* a : __variables) {
if (!is_expr(a)) {
_assumptions.finalize(); _consequences.finalize(); _variables.finalize();
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "variable is not an expression");
return Z3_L_UNDEF;
}
_variables.push_back(to_expr(a));
@ -590,7 +595,7 @@ extern "C" {
expr_ref_vector result(m), vars(m);
for (ast* a : to_ast_vector_ref(vs)) {
if (!is_expr(a)) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "cube contains a non-expression");
}
else {
vars.push_back(to_expr(a));

View file

@ -67,7 +67,7 @@ extern "C" {
LOG_Z3_stats_get_key(c, s, idx);
RESET_ERROR_CODE();
if (idx >= to_stats_ref(s).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return "";
}
return to_stats_ref(s).get_key(idx);
@ -79,7 +79,7 @@ extern "C" {
LOG_Z3_stats_is_uint(c, s, idx);
RESET_ERROR_CODE();
if (idx >= to_stats_ref(s).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return Z3_FALSE;
}
return to_stats_ref(s).is_uint(idx);
@ -91,7 +91,7 @@ extern "C" {
LOG_Z3_stats_is_double(c, s, idx);
RESET_ERROR_CODE();
if (idx >= to_stats_ref(s).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return Z3_FALSE;
}
return !to_stats_ref(s).is_uint(idx);
@ -103,11 +103,11 @@ extern "C" {
LOG_Z3_stats_get_uint_value(c, s, idx);
RESET_ERROR_CODE();
if (idx >= to_stats_ref(s).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0;
}
if (!to_stats_ref(s).is_uint(idx)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return to_stats_ref(s).get_uint_value(idx);
@ -119,11 +119,11 @@ extern "C" {
LOG_Z3_stats_get_double_value(c, s, idx);
RESET_ERROR_CODE();
if (idx >= to_stats_ref(s).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0.0;
}
if (to_stats_ref(s).is_uint(idx)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0.0;
}
return to_stats_ref(s).get_double_value(idx);

View file

@ -52,7 +52,7 @@ extern "C" {
RESET_ERROR_CODE();
tactic_cmd * t = mk_c(c)->find_tactic_cmd(symbol(name));
if (t == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
tactic * new_t = t->mk(mk_c(c)->m());
@ -82,7 +82,7 @@ extern "C" {
RESET_ERROR_CODE();
probe_info * p = mk_c(c)->find_probe(symbol(name));
if (p == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
probe * new_p = p->get();
@ -324,7 +324,7 @@ extern "C" {
LOG_Z3_get_tactic_name(c, idx);
RESET_ERROR_CODE();
if (idx >= mk_c(c)->num_tactics()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return "";
}
return mk_c(c)->get_tactic(idx)->get_name().bare_str();
@ -344,7 +344,7 @@ extern "C" {
LOG_Z3_get_probe_name(c, idx);
RESET_ERROR_CODE();
if (idx >= mk_c(c)->num_probes()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return "";
}
return mk_c(c)->get_probe(idx)->get_name().bare_str();
@ -381,7 +381,7 @@ extern "C" {
RESET_ERROR_CODE();
tactic_cmd * t = mk_c(c)->find_tactic_cmd(symbol(name));
if (t == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return "";
}
return t->get_descr();
@ -394,7 +394,7 @@ extern "C" {
RESET_ERROR_CODE();
probe_info * p = mk_c(c)->find_probe(symbol(name));
if (p == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return "";
}
return p->get_descr();
@ -504,7 +504,7 @@ extern "C" {
LOG_Z3_apply_result_get_subgoal(c, r, i);
RESET_ERROR_CODE();
if (i > to_apply_result(r)->m_subgoals.size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
Z3_goal_ref * g = alloc(Z3_goal_ref, *mk_c(c));

View file

@ -167,11 +167,6 @@ namespace z3 {
}
void check_parser_error() const {
Z3_error_code e = Z3_get_error_code(*this);
if (e != Z3_OK && enable_exceptions()) {
Z3_string s = Z3_get_parser_error(*this);
if (s && *s) Z3_THROW(exception(s));
}
check_error();
}
@ -252,7 +247,6 @@ namespace z3 {
*/
sort array_sort(sort d, sort r);
sort array_sort(sort_vector const& d, sort r);
/**
\brief Return an enumeration sort: enum_names[0], ..., enum_names[n-1].
\c cs and \c ts are output parameters. The method stores in \c cs the constants corresponding to the enumerated elements,
@ -675,7 +669,21 @@ namespace z3 {
\brief Return true if this expression is a quantifier.
*/
bool is_quantifier() const { return kind() == Z3_QUANTIFIER_AST; }
/**
\brief Return true if this expression is a universal quantifier.
*/
bool is_forall() const { return 0 != Z3_is_quantifier_forall(ctx(), m_ast); }
/**
\brief Return true if this expression is an existential quantifier.
*/
bool is_exists() const { return 0 != Z3_is_quantifier_exists(ctx(), m_ast); }
/**
\brief Return true if this expression is a lambda expression.
*/
bool is_lambda() const { return 0 != Z3_is_lambda(ctx(), m_ast); }
/**
\brief Return true if this expression is a variable.
*/
bool is_var() const { return kind() == Z3_VAR_AST; }
@ -1638,6 +1646,31 @@ namespace z3 {
array<Z3_app> vars(xs);
Z3_ast r = Z3_mk_exists_const(b.ctx(), 0, vars.size(), vars.ptr(), 0, 0, b); b.check_error(); return expr(b.ctx(), r);
}
inline expr lambda(expr const & x, expr const & b) {
check_context(x, b);
Z3_app vars[] = {(Z3_app) x};
Z3_ast r = Z3_mk_lambda_const(b.ctx(), 1, vars, b); b.check_error(); return expr(b.ctx(), r);
}
inline expr lambda(expr const & x1, expr const & x2, expr const & b) {
check_context(x1, b); check_context(x2, b);
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2};
Z3_ast r = Z3_mk_lambda_const(b.ctx(), 2, vars, b); b.check_error(); return expr(b.ctx(), r);
}
inline expr lambda(expr const & x1, expr const & x2, expr const & x3, expr const & b) {
check_context(x1, b); check_context(x2, b); check_context(x3, b);
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3 };
Z3_ast r = Z3_mk_lambda_const(b.ctx(), 3, vars, b); b.check_error(); return expr(b.ctx(), r);
}
inline expr lambda(expr const & x1, expr const & x2, expr const & x3, expr const & x4, expr const & b) {
check_context(x1, b); check_context(x2, b); check_context(x3, b); check_context(x4, b);
Z3_app vars[] = {(Z3_app) x1, (Z3_app) x2, (Z3_app) x3, (Z3_app) x4 };
Z3_ast r = Z3_mk_lambda_const(b.ctx(), 4, vars, b); b.check_error(); return expr(b.ctx(), r);
}
inline expr lambda(expr_vector const & xs, expr const & b) {
array<Z3_app> vars(xs);
Z3_ast r = Z3_mk_lambda_const(b.ctx(), vars.size(), vars.ptr(), b); b.check_error(); return expr(b.ctx(), r);
}
inline expr pble(expr_vector const& es, int const* coeffs, int bound) {
assert(es.size() > 0);
context& ctx = es[0].ctx();
@ -2521,7 +2554,6 @@ namespace z3 {
array<Z3_sort> dom(d);
Z3_sort s = Z3_mk_array_sort_n(m_ctx, dom.size(), dom.ptr(), r); check_error(); return sort(*this, s);
}
inline sort context::enumeration_sort(char const * name, unsigned n, char const * const * enum_names, func_decl_vector & cs, func_decl_vector & ts) {
array<Z3_symbol> _enum_names(n);
for (unsigned i = 0; i < n; i++) { _enum_names[i] = Z3_mk_string_symbol(*this, enum_names[i]); }
@ -2785,12 +2817,8 @@ namespace z3 {
a.check_error();
return expr(a.ctx(), r);
}
inline expr select(expr const & a, int i) { return select(a, a.ctx().num_val(i, a.get_sort().array_domain())); }
inline expr store(expr const & a, expr const & i, expr const & v) {
check_context(a, i); check_context(a, v);
Z3_ast r = Z3_mk_store(a.ctx(), a, i, v);
a.check_error();
return expr(a.ctx(), r);
inline expr select(expr const & a, int i) {
return select(a, a.ctx().num_val(i, a.get_sort().array_domain()));
}
inline expr select(expr const & a, expr_vector const & i) {
check_context(a, i);
@ -2800,6 +2828,13 @@ namespace z3 {
return expr(a.ctx(), r);
}
inline expr store(expr const & a, expr const & i, expr const & v) {
check_context(a, i); check_context(a, v);
Z3_ast r = Z3_mk_store(a.ctx(), a, i, v);
a.check_error();
return expr(a.ctx(), r);
}
inline expr store(expr const & a, int i, expr const & v) { return store(a, a.ctx().num_val(i, a.get_sort().array_domain()), v); }
inline expr store(expr const & a, expr i, int v) { return store(a, i, a.ctx().num_val(v, a.get_sort().array_range())); }
inline expr store(expr const & a, int i, int v) {

View file

@ -43,7 +43,7 @@ namespace Microsoft.Z3
(!Object.ReferenceEquals(a, null) &&
!Object.ReferenceEquals(b, null) &&
a.Context.nCtx == b.Context.nCtx &&
Native.Z3_is_eq_ast(a.Context.nCtx, a.NativeObject, b.NativeObject) != 0);
0 != Native.Z3_is_eq_ast(a.Context.nCtx, a.NativeObject, b.NativeObject));
}
/// <summary>

View file

@ -37,7 +37,7 @@ namespace Microsoft.Z3
{
Contract.Requires(k != null);
return Native.Z3_ast_map_contains(Context.nCtx, NativeObject, k.NativeObject) != 0;
return 0 != Native.Z3_ast_map_contains(Context.nCtx, NativeObject, k.NativeObject);
}
/// <summary>

View file

@ -37,6 +37,6 @@ namespace Microsoft.Z3
{
Contract.Requires(ctx != null);
}
#endregion
#endregion
}
}

View file

@ -84,6 +84,7 @@ set(Z3_DOTNET_ASSEMBLY_SOURCES_IN_SRC_TREE
IntNum.cs
IntSort.cs
IntSymbol.cs
Lambda.cs
ListSort.cs
Log.cs
Model.cs

View file

@ -1963,7 +1963,7 @@ namespace Microsoft.Z3
Contract.Ensures(Contract.Result<IntExpr>() != null);
CheckContextMatch(t);
return new IntExpr(this, Native.Z3_mk_bv2int(nCtx, t.NativeObject, (signed) ? 1 : 0));
return new IntExpr(this, Native.Z3_mk_bv2int(nCtx, t.NativeObject, (byte)(signed ? 1 : 0)));
}
/// <summary>
@ -1980,7 +1980,7 @@ namespace Microsoft.Z3
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvadd_no_overflow(nCtx, t1.NativeObject, t2.NativeObject, (isSigned) ? 1 : 0));
return new BoolExpr(this, Native.Z3_mk_bvadd_no_overflow(nCtx, t1.NativeObject, t2.NativeObject, (byte)(isSigned ? 1 : 0)));
}
/// <summary>
@ -2031,7 +2031,7 @@ namespace Microsoft.Z3
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvsub_no_underflow(nCtx, t1.NativeObject, t2.NativeObject, (isSigned) ? 1 : 0));
return new BoolExpr(this, Native.Z3_mk_bvsub_no_underflow(nCtx, t1.NativeObject, t2.NativeObject, (byte)(isSigned ? 1 : 0)));
}
/// <summary>
@ -2080,7 +2080,7 @@ namespace Microsoft.Z3
CheckContextMatch(t1);
CheckContextMatch(t2);
return new BoolExpr(this, Native.Z3_mk_bvmul_no_overflow(nCtx, t1.NativeObject, t2.NativeObject, (isSigned) ? 1 : 0));
return new BoolExpr(this, Native.Z3_mk_bvmul_no_overflow(nCtx, t1.NativeObject, t2.NativeObject, (byte)(isSigned ? 1 : 0)));
}
/// <summary>
@ -2777,25 +2777,25 @@ namespace Microsoft.Z3
/// <summary>
/// Create an at-most-k constraint.
/// </summary>
public BoolExpr MkAtMost(BoolExpr[] args, uint k)
public BoolExpr MkAtMost(IEnumerable<BoolExpr> args, uint k)
{
Contract.Requires(args != null);
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
CheckContextMatch<BoolExpr>(args);
return new BoolExpr(this, Native.Z3_mk_atmost(nCtx, (uint) args.Length,
AST.ArrayToNative(args), k));
return new BoolExpr(this, Native.Z3_mk_atmost(nCtx, (uint) args.Count(),
AST.EnumToNative(args), k));
}
/// <summary>
/// Create an at-least-k constraint.
/// </summary>
public BoolExpr MkAtLeast(BoolExpr[] args, uint k)
public BoolExpr MkAtLeast(IEnumerable<BoolExpr> args, uint k)
{
Contract.Requires(args != null);
Contract.Requires(Contract.Result<BoolExpr[]>() != null);
CheckContextMatch<BoolExpr>(args);
return new BoolExpr(this, Native.Z3_mk_atleast(nCtx, (uint) args.Length,
AST.ArrayToNative(args), k));
return new BoolExpr(this, Native.Z3_mk_atleast(nCtx, (uint) args.Count(),
AST.EnumToNative(args), k));
}
/// <summary>
@ -3135,8 +3135,8 @@ namespace Microsoft.Z3
public BitVecNum MkBV(bool[] bits)
{
Contract.Ensures(Contract.Result<BitVecNum>() != null);
int[] _bits = new int[bits.Length];
for (int i = 0; i < bits.Length; ++i) _bits[i] = bits[i] ? 1 : 0;
byte[] _bits = new byte[bits.Length];
for (int i = 0; i < bits.Length; ++i) _bits[i] = (byte)(bits[i] ? 1 : 0);
return (BitVecNum)Expr.Create(this, Native.Z3_mk_bv_numeral(nCtx, (uint)bits.Length, _bits));
}
@ -3292,6 +3292,53 @@ namespace Microsoft.Z3
return MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID);
}
/// <summary>
/// Create a lambda expression.
/// </summary>
/// <remarks>
/// Creates a lambda expression.
/// <paramref name="sorts"/> is an array
/// with the sorts of the bound variables, <paramref name="names"/> is an array with the
/// 'names' of the bound variables, and <paramref name="body"/> is the body of the
/// lambda.
/// Note that the bound variables are de-Bruijn indices created using <see cref="MkBound"/>.
/// Z3 applies the convention that the last element in <paramref name="names"/> and
/// <paramref name="sorts"/> refers to the variable with index 0, the second to last element
/// of <paramref name="names"/> and <paramref name="sorts"/> refers to the variable
/// with index 1, etc.
/// </remarks>
/// <param name="sorts">the sorts of the bound variables.</param>
/// <param name="names">names of the bound variables</param>
/// <param name="body">the body of the quantifier.</param>
public Lambda MkLambda(Sort[] sorts, Symbol[] names, Expr body)
{
Contract.Requires(sorts != null);
Contract.Requires(names != null);
Contract.Requires(body != null);
Contract.Requires(sorts.Length == names.Length);
Contract.Requires(Contract.ForAll(sorts, s => s != null));
Contract.Requires(Contract.ForAll(names, n => n != null));
Contract.Ensures(Contract.Result<Lambda>() != null);
return new Lambda(this, sorts, names, body);
}
/// <summary>
/// Create a lambda expression.
/// </summary>
/// <remarks>
/// Creates a lambda expression using a list of constants that will
/// form the set of bound variables.
/// <seealso cref="MkLambda(Sort[], Symbol[], Expr)"/>
/// </remarks>
public Lambda MkLambda(Expr[] boundConstants, Expr body)
{
Contract.Requires(body != null);
Contract.Requires(boundConstants != null && Contract.ForAll(boundConstants, b => b != null));
Contract.Ensures(Contract.Result<Lambda>() != null);
return new Lambda(this, boundConstants, body);
}
#endregion
#endregion // Expr
@ -4139,7 +4186,7 @@ namespace Microsoft.Z3
public FPNum MkFPInf(FPSort s, bool negative)
{
Contract.Ensures(Contract.Result<FPRMExpr>() != null);
return new FPNum(this, Native.Z3_mk_fpa_inf(nCtx, s.NativeObject, negative ? 1 : 0));
return new FPNum(this, Native.Z3_mk_fpa_inf(nCtx, s.NativeObject, (byte)(negative ? 1 : 0)));
}
/// <summary>
@ -4150,7 +4197,7 @@ namespace Microsoft.Z3
public FPNum MkFPZero(FPSort s, bool negative)
{
Contract.Ensures(Contract.Result<FPRMExpr>() != null);
return new FPNum(this, Native.Z3_mk_fpa_zero(nCtx, s.NativeObject, negative ? 1 : 0));
return new FPNum(this, Native.Z3_mk_fpa_zero(nCtx, s.NativeObject, (byte)(negative ? 1 : 0)));
}
/// <summary>
@ -4196,7 +4243,7 @@ namespace Microsoft.Z3
public FPNum MkFPNumeral(bool sgn, uint sig, int exp, FPSort s)
{
Contract.Ensures(Contract.Result<FPRMExpr>() != null);
return new FPNum(this, Native.Z3_mk_fpa_numeral_int_uint(nCtx, sgn ? 1 : 0, exp, sig, s.NativeObject));
return new FPNum(this, Native.Z3_mk_fpa_numeral_int_uint(nCtx, (byte)(sgn ? 1 : 0), exp, sig, s.NativeObject));
}
/// <summary>
@ -4209,7 +4256,7 @@ namespace Microsoft.Z3
public FPNum MkFPNumeral(bool sgn, Int64 exp, UInt64 sig, FPSort s)
{
Contract.Ensures(Contract.Result<FPRMExpr>() != null);
return new FPNum(this, Native.Z3_mk_fpa_numeral_int64_uint64(nCtx, sgn ? 1 : 0, exp, sig, s.NativeObject));
return new FPNum(this, Native.Z3_mk_fpa_numeral_int64_uint64(nCtx, (byte)(sgn ? 1 : 0), exp, sig, s.NativeObject));
}
/// <summary>

View file

@ -239,7 +239,7 @@ namespace Microsoft.Z3
/// </summary>
public bool IsAlgebraicNumber
{
get { return Native.Z3_is_algebraic_number(Context.nCtx, NativeObject) != 0; }
get { return 0 != Native.Z3_is_algebraic_number(Context.nCtx, NativeObject); }
}
#endregion
@ -789,7 +789,7 @@ namespace Microsoft.Z3
/// Check whether expression is a string constant.
/// </summary>
/// <returns>a Boolean</returns>
public bool IsString { get { return IsApp && 0 != Native.Z3_is_string(Context.nCtx, NativeObject); } }
public bool IsString { get { return IsApp && Native.Z3_is_string(Context.nCtx, NativeObject) != 0; } }
/// <summary>
/// Retrieve string corresponding to string constant.
@ -1458,7 +1458,7 @@ namespace Microsoft.Z3
{
get
{
return (Native.Z3_is_app(Context.nCtx, NativeObject) != 0 &&
return (Native.Z3_is_app(Context.nCtx, NativeObject) != 0 &&
Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == (uint)Z3_sort_kind.Z3_FINITE_DOMAIN_SORT);
}
}
@ -1822,11 +1822,12 @@ namespace Microsoft.Z3
IntPtr s = Native.Z3_get_sort(ctx.nCtx, obj);
Z3_sort_kind sk = (Z3_sort_kind)Native.Z3_get_sort_kind(ctx.nCtx, s);
if (Native.Z3_is_algebraic_number(ctx.nCtx, obj) != 0) // is this a numeral ast?
if (0 != Native.Z3_is_algebraic_number(ctx.nCtx, obj)) // is this a numeral ast?
return new AlgebraicNum(ctx, obj);
if (Native.Z3_is_numeral_ast(ctx.nCtx, obj) != 0)
{
switch (sk)
{
case Z3_sort_kind.Z3_INT_SORT: return new IntNum(ctx, obj);

View file

@ -111,7 +111,7 @@ namespace Microsoft.Z3
/// </summary>
public string Exponent(bool biased = true)
{
return Native.Z3_fpa_get_numeral_exponent_string(Context.nCtx, NativeObject, biased ? 1 : 0);
return Native.Z3_fpa_get_numeral_exponent_string(Context.nCtx, NativeObject, (byte)(biased ? 1 : 0));
}
/// <summary>
@ -120,7 +120,7 @@ namespace Microsoft.Z3
public Int64 ExponentInt64(bool biased = true)
{
Int64 result = 0;
if (Native.Z3_fpa_get_numeral_exponent_int64(Context.nCtx, NativeObject, ref result, biased ? 1 : 0) == 0)
if (Native.Z3_fpa_get_numeral_exponent_int64(Context.nCtx, NativeObject, ref result, (byte)(biased? 1 : 0)) == 0)
throw new Z3Exception("Exponent is not a 64 bit integer");
return result;
}
@ -133,7 +133,7 @@ namespace Microsoft.Z3
/// </remarks>
public BitVecExpr ExponentBV(bool biased = true)
{
return new BitVecExpr(Context, Native.Z3_fpa_get_numeral_exponent_bv(Context.nCtx, NativeObject, biased ? 1 : 0));
return new BitVecExpr(Context, Native.Z3_fpa_get_numeral_exponent_bv(Context.nCtx, NativeObject, (byte)(biased ? 1 : 0)));
}
/// <summary>

View file

@ -91,7 +91,7 @@ namespace Microsoft.Z3
/// all contexts globally.</remarks>
public static void ToggleWarningMessages(bool enabled)
{
Native.Z3_toggle_warning_messages((enabled) ? 1 : 0);
Native.Z3_toggle_warning_messages((byte)(enabled ? 1 : 0));
}
/// <summary>

View file

@ -251,7 +251,7 @@ namespace Microsoft.Z3
internal Goal(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); }
internal Goal(Context ctx, bool models, bool unsatCores, bool proofs)
: base(ctx, Native.Z3_mk_goal(ctx.nCtx, (models) ? 1 : 0, (unsatCores) ? 1 : 0, (proofs) ? 1 : 0))
: base(ctx, Native.Z3_mk_goal(ctx.nCtx, (byte)(models ? 1 : 0), (byte)(unsatCores ? 1 : 0), (byte)(proofs ? 1 : 0)))
{
Contract.Requires(ctx != null);
}

152
src/api/dotnet/Lambda.cs Normal file
View file

@ -0,0 +1,152 @@
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
Lambda.cs
Abstract:
Z3 Managed API: Lambda
Author:
Christoph Wintersteiger (cwinter) 2012-03-19
Notes:
--*/
using System;
using System.Diagnostics.Contracts;
namespace Microsoft.Z3
{
/// <summary>
/// Lambda expressions.
/// </summary>
[ContractVerification(true)]
public class Lambda : ArrayExpr
{
/// <summary>
/// The number of bound variables.
/// </summary>
public uint NumBound
{
get { return Native.Z3_get_quantifier_num_bound(Context.nCtx, NativeObject); }
}
/// <summary>
/// The symbols for the bound variables.
/// </summary>
public Symbol[] BoundVariableNames
{
get
{
Contract.Ensures(Contract.Result<Symbol[]>() != null);
uint n = NumBound;
Symbol[] res = new Symbol[n];
for (uint i = 0; i < n; i++)
res[i] = Symbol.Create(Context, Native.Z3_get_quantifier_bound_name(Context.nCtx, NativeObject, i));
return res;
}
}
/// <summary>
/// The sorts of the bound variables.
/// </summary>
public Sort[] BoundVariableSorts
{
get
{
Contract.Ensures(Contract.Result<Sort[]>() != null);
uint n = NumBound;
Sort[] res = new Sort[n];
for (uint i = 0; i < n; i++)
res[i] = Sort.Create(Context, Native.Z3_get_quantifier_bound_sort(Context.nCtx, NativeObject, i));
return res;
}
}
/// <summary>
/// The body of the lambda.
/// </summary>
public Expr Body
{
get
{
Contract.Ensures(Contract.Result<BoolExpr>() != null);
return new BoolExpr(Context, Native.Z3_get_quantifier_body(Context.nCtx, NativeObject));
}
}
/// <summary>
/// Translates (copies) the lambda to the Context <paramref name="ctx"/>.
/// </summary>
/// <param name="ctx">A context</param>
/// <returns>A copy of the lambda which is associated with <paramref name="ctx"/></returns>
new public Lambda Translate(Context ctx)
{
return (Lambda)base.Translate(ctx);
}
#region Internal
[ContractVerification(false)] // F: Clousot ForAll decompilation gets confused below. Setting verification off until I fixed the bug
internal Lambda(Context ctx, Sort[] sorts, Symbol[] names, Expr body)
: base(ctx, IntPtr.Zero)
{
Contract.Requires(ctx != null);
Contract.Requires(sorts != null);
Contract.Requires(names != null);
Contract.Requires(body != null);
Contract.Requires(sorts.Length == names.Length);
Contract.Requires(Contract.ForAll(sorts, s => s != null));
Contract.Requires(Contract.ForAll(names, n => n != null));
Context.CheckContextMatch<Sort>(sorts);
Context.CheckContextMatch<Symbol>(names);
Context.CheckContextMatch(body);
if (sorts.Length != names.Length)
throw new Z3Exception("Number of sorts does not match number of names");
NativeObject = Native.Z3_mk_lambda(ctx.nCtx,
AST.ArrayLength(sorts), AST.ArrayToNative(sorts),
Symbol.ArrayToNative(names),
body.NativeObject);
}
[ContractVerification(false)] // F: Clousot ForAll decompilation gets confused below. Setting verification off until I fixed the bug
internal Lambda(Context ctx, Expr[] bound, Expr body)
: base(ctx, IntPtr.Zero)
{
Contract.Requires(ctx != null);
Contract.Requires(body != null);
Contract.Requires(bound != null && bound.Length > 0 && Contract.ForAll(bound, n => n != null));
Context.CheckContextMatch<Expr>(bound);
Context.CheckContextMatch(body);
NativeObject = Native.Z3_mk_lambda_const(ctx.nCtx,
AST.ArrayLength(bound), AST.ArrayToNative(bound),
body.NativeObject);
}
internal Lambda(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); }
#if DEBUG
internal override void CheckNativeObject(IntPtr obj)
{
if ((Z3_ast_kind)Native.Z3_get_ast_kind(Context.nCtx, obj) != Z3_ast_kind.Z3_QUANTIFIER_AST)
throw new Z3Exception("Underlying object is not a quantifier");
base.CheckNativeObject(obj);
}
#endif
#endregion
}
}

View file

@ -227,7 +227,7 @@ namespace Microsoft.Z3
Contract.Ensures(Contract.Result<Expr>() != null);
IntPtr v = IntPtr.Zero;
if (Native.Z3_model_eval(Context.nCtx, NativeObject, t.NativeObject, (completion) ? 1 : 0, ref v) == 0)
if (Native.Z3_model_eval(Context.nCtx, NativeObject, t.NativeObject, (byte)(completion ? 1 : 0), ref v) == (byte)0)
throw new ModelEvaluationFailedException();
else
return Expr.Create(Context, v);

View file

@ -35,7 +35,7 @@ namespace Microsoft.Z3
{
Contract.Requires(name != null);
Native.Z3_params_set_bool(Context.nCtx, NativeObject, name.NativeObject, (value) ? 1 : 0);
Native.Z3_params_set_bool(Context.nCtx, NativeObject, name.NativeObject, (byte)(value ? 1 : 0));
return this;
}
@ -90,7 +90,7 @@ namespace Microsoft.Z3
/// </summary>
public Params Add(string name, bool value)
{
Native.Z3_params_set_bool(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, (value) ? 1 : 0);
Native.Z3_params_set_bool(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, (byte)(value ? 1 : 0));
return this;
}

View file

@ -33,7 +33,7 @@ namespace Microsoft.Z3
/// </summary>
public bool IsUniversal
{
get { return Native.Z3_is_quantifier_forall(Context.nCtx, NativeObject) != 0; }
get { return 0 != Native.Z3_is_quantifier_forall(Context.nCtx, NativeObject); }
}
/// <summary>
@ -41,7 +41,7 @@ namespace Microsoft.Z3
/// </summary>
public bool IsExistential
{
get { return !IsUniversal; }
get { return 0 != Native.Z3_is_quantifier_exists(Context.nCtx, NativeObject); }
}
/// <summary>
@ -193,7 +193,7 @@ namespace Microsoft.Z3
if (noPatterns == null && quantifierID == null && skolemID == null)
{
NativeObject = Native.Z3_mk_quantifier(ctx.nCtx, (isForall) ? 1 : 0, weight,
NativeObject = Native.Z3_mk_quantifier(ctx.nCtx, (byte)(isForall ? 1 : 0) , weight,
AST.ArrayLength(patterns), AST.ArrayToNative(patterns),
AST.ArrayLength(sorts), AST.ArrayToNative(sorts),
Symbol.ArrayToNative(names),
@ -201,7 +201,7 @@ namespace Microsoft.Z3
}
else
{
NativeObject = Native.Z3_mk_quantifier_ex(ctx.nCtx, (isForall) ? 1 : 0, weight,
NativeObject = Native.Z3_mk_quantifier_ex(ctx.nCtx, (byte)(isForall ? 1 : 0), weight,
AST.GetNativeObject(quantifierID), AST.GetNativeObject(skolemID),
AST.ArrayLength(patterns), AST.ArrayToNative(patterns),
AST.ArrayLength(noPatterns), AST.ArrayToNative(noPatterns),
@ -229,14 +229,14 @@ namespace Microsoft.Z3
if (noPatterns == null && quantifierID == null && skolemID == null)
{
NativeObject = Native.Z3_mk_quantifier_const(ctx.nCtx, (isForall) ? 1 : 0, weight,
NativeObject = Native.Z3_mk_quantifier_const(ctx.nCtx, (byte)(isForall ? 1 : 0) , weight,
AST.ArrayLength(bound), AST.ArrayToNative(bound),
AST.ArrayLength(patterns), AST.ArrayToNative(patterns),
body.NativeObject);
}
else
{
NativeObject = Native.Z3_mk_quantifier_const_ex(ctx.nCtx, (isForall) ? 1 : 0, weight,
NativeObject = Native.Z3_mk_quantifier_const_ex(ctx.nCtx, (byte)(isForall ? 1 : 0), weight,
AST.GetNativeObject(quantifierID), AST.GetNativeObject(skolemID),
AST.ArrayLength(bound), AST.ArrayToNative(bound),
AST.ArrayLength(patterns), AST.ArrayToNative(patterns),

View file

@ -41,7 +41,7 @@ namespace Microsoft.Z3
(!Object.ReferenceEquals(a, null) &&
!Object.ReferenceEquals(b, null) &&
a.Context == b.Context &&
Native.Z3_is_eq_sort(a.Context.nCtx, a.NativeObject, b.NativeObject) != 0);
0 != Native.Z3_is_eq_sort(a.Context.nCtx, a.NativeObject, b.NativeObject));
}
/// <summary>

View file

@ -141,6 +141,7 @@ set(Z3_JAVA_JAR_SOURCE_FILES
IntNum.java
IntSort.java
IntSymbol.java
Lambda.java
ListSort.java
Log.java
ModelDecRefQueue.java

View file

@ -518,7 +518,7 @@ public class Context implements AutoCloseable {
/**
* Creates a fresh constant function declaration with a name prefixed with
* {@code prefix"}.
* {@code prefix}.
* @see #mkFuncDecl(String,Sort,Sort)
* @see #mkFuncDecl(String,Sort[],Sort)
**/
@ -696,7 +696,7 @@ public class Context implements AutoCloseable {
}
/**
* Creates the equality {@code x"/> = <paramref name="y}.
* Creates the equality {@code x = y}
**/
public BoolExpr mkEq(Expr x, Expr y)
{
@ -2498,6 +2498,40 @@ public class Context implements AutoCloseable {
quantifierID, skolemID);
}
/**
* Create a lambda expression.
*
* {@code sorts} is an array
* with the sorts of the bound variables, {@code names} is an array with the
* 'names' of the bound variables, and {@code body} is the body of the
* lambda.
* Note that the bound variables are de-Bruijn indices created using {@see #MkBound}
* Z3 applies the convention that the last element in {@code names} and
* {@code sorts} refers to the variable with index 0, the second to last element
* of {@code names} and {@code sorts} refers to the variable
* with index 1, etc.
*
* @param sorts the sorts of the bound variables.
* @param names names of the bound variables.
* @param body the body of the quantifier.
**/
public Lambda mkLambda(Sort[] sorts, Symbol[] names, Expr body)
{
return Lambda.of(this, sorts, names, body);
}
/**
* Create a lambda expression.
*
* Creates a lambda expression using a list of constants that will
* form the set of bound variables.
**/
public Lambda mkLambda(Expr[] boundConstants, Expr body)
{
return Lambda.of(this, boundConstants, body);
}
/**
* Selects the format used for pretty-printing expressions.
* Remarks: The
@ -2653,7 +2687,7 @@ public class Context implements AutoCloseable {
/**
* Create a tactic that applies {@code t1} to a Goal and then
* {@code t2"/> to every subgoal produced by <paramref name="t1}.
* {@code t2} to every subgoal produced by {@code t1}
**/
public Tactic andThen(Tactic t1, Tactic t2, Tactic... ts)
@ -2734,7 +2768,7 @@ public class Context implements AutoCloseable {
/**
* Create a tactic that applies {@code t1} to a given goal if the
* probe {@code p"/> evaluates to true and <paramref name="t2}
* probe {@code p} evaluates to true and {@code t2}
* otherwise.
**/
public Tactic cond(Probe p, Tactic t1, Tactic t2)
@ -2895,7 +2929,7 @@ public class Context implements AutoCloseable {
}
/**
* Create a probe that evaluates to "true" when the value returned by
* Create a probe that evaluates to {@code true} when the value returned by
* {@code p1} is less than the value returned by {@code p2}
**/
public Probe lt(Probe p1, Probe p2)
@ -2907,7 +2941,7 @@ public class Context implements AutoCloseable {
}
/**
* Create a probe that evaluates to "true" when the value returned by
* Create a probe that evaluates to {@code true} when the value returned by
* {@code p1} is greater than the value returned by {@code p2}
**/
public Probe gt(Probe p1, Probe p2)
@ -2919,7 +2953,7 @@ public class Context implements AutoCloseable {
}
/**
* Create a probe that evaluates to "true" when the value returned by
* Create a probe that evaluates to {@code true} when the value returned by
* {@code p1} is less than or equal the value returned by
* {@code p2}
**/
@ -2932,7 +2966,7 @@ public class Context implements AutoCloseable {
}
/**
* Create a probe that evaluates to "true" when the value returned by
* Create a probe that evaluates to {@code true} when the value returned by
* {@code p1} is greater than or equal the value returned by
* {@code p2}
**/
@ -2945,7 +2979,7 @@ public class Context implements AutoCloseable {
}
/**
* Create a probe that evaluates to "true" when the value returned by
* Create a probe that evaluates to {@code true} when the value returned by
* {@code p1} is equal to the value returned by {@code p2}
**/
public Probe eq(Probe p1, Probe p2)
@ -2957,7 +2991,7 @@ public class Context implements AutoCloseable {
}
/**
* Create a probe that evaluates to "true" when the value {@code p1} and {@code p2} evaluate to "true".
* Create a probe that evaluates to {@code true} when the value {@code p1} and {@code p2} evaluate to {@code true}.
**/
public Probe and(Probe p1, Probe p2)
{
@ -2968,7 +3002,7 @@ public class Context implements AutoCloseable {
}
/**
* Create a probe that evaluates to "true" when the value {@code p1} or {@code p2} evaluate to "true".
* Create a probe that evaluates to {@code true} when the value {@code p1} or {@code p2} evaluate to {@code true}.
**/
public Probe or(Probe p1, Probe p2)
{
@ -2979,7 +3013,7 @@ public class Context implements AutoCloseable {
}
/**
* Create a probe that evaluates to "true" when the value {@code p} does not evaluate to "true".
* Create a probe that evaluates to {@code true} when the value {@code p} does not evaluate to {@code true}.
**/
public Probe not(Probe p)
{

134
src/api/java/Lambda.java Normal file
View file

@ -0,0 +1,134 @@
/**
Copyright (c) 2017 Microsoft Corporation
Module Name:
Lambda.java
Abstract:
Z3 Java API: Lambda
Author:
Christoph Wintersteiger (cwinter) 2012-03-19
Notes:
**/
package com.microsoft.z3;
import com.microsoft.z3.enumerations.Z3_ast_kind;
/**
* Lambda expressions.
*/public class Lambda extends ArrayExpr
{
/**
* The number of bound variables.
**/
public int getNumBound()
{
return Native.getQuantifierNumBound(getContext().nCtx(), getNativeObject());
}
/**
* The symbols for the bound variables.
*
* @throws Z3Exception
**/
public Symbol[] getBoundVariableNames()
{
int n = getNumBound();
Symbol[] res = new Symbol[n];
for (int i = 0; i < n; i++)
res[i] = Symbol.create(getContext(), Native.getQuantifierBoundName(
getContext().nCtx(), getNativeObject(), i));
return res;
}
/**
* The sorts of the bound variables.
*
* @throws Z3Exception
**/
public Sort[] getBoundVariableSorts()
{
int n = getNumBound();
Sort[] res = new Sort[n];
for (int i = 0; i < n; i++)
res[i] = Sort.create(getContext(), Native.getQuantifierBoundSort(
getContext().nCtx(), getNativeObject(), i));
return res;
}
/**
* The body of the quantifier.
*
* @throws Z3Exception
**/
public BoolExpr getBody()
{
return new BoolExpr(getContext(), Native.getQuantifierBody(getContext()
.nCtx(), getNativeObject()));
}
/**
* Translates (copies) the quantifier to the Context {@code ctx}.
*
* @param ctx A context
*
* @return A copy of the quantifier which is associated with {@code ctx}
* @throws Z3Exception on error
**/
public Lambda translate(Context ctx)
{
return (Lambda) super.translate(ctx);
}
public static Lambda of(Context ctx, Sort[] sorts, Symbol[] names, Expr body)
{
ctx.checkContextMatch(sorts);
ctx.checkContextMatch(names);
ctx.checkContextMatch(body);
if (sorts.length != names.length)
throw new Z3Exception("Number of sorts does not match number of names");
long nativeObject = Native.mkLambda(ctx.nCtx(),
AST.arrayLength(sorts), AST.arrayToNative(sorts),
Symbol.arrayToNative(names),
body.getNativeObject());
return new Lambda(ctx, nativeObject);
}
/**
* @param ctx Context to create the lambda on.
* @param bound Bound variables.
* @param body Body of the lambda expression.
*/
public static Lambda of(Context ctx, Expr[] bound, Expr body) {
ctx.checkContextMatch(body);
long nativeObject = Native.mkLambdaConst(ctx.nCtx(),
AST.arrayLength(bound), AST.arrayToNative(bound),
body.getNativeObject());
return new Lambda(ctx, nativeObject);
}
private Lambda(Context ctx, long obj)
{
super(ctx, obj);
}
}

View file

@ -91,11 +91,11 @@ public class Model extends Z3Object {
return null;
else
{
if (!Native.isAsArray(getContext().nCtx(), n))
throw new Z3Exception(
"Argument was not an array constant");
long fd = Native.getAsArrayFuncDecl(getContext().nCtx(), n);
return getFuncInterp(new FuncDecl(getContext(), fd));
if (Native.isAsArray(getContext().nCtx(), n)) {
long fd = Native.getAsArrayFuncDecl(getContext().nCtx(), n);
return getFuncInterp(new FuncDecl(getContext(), fd));
}
return null;
}
} else
{

View file

@ -37,7 +37,7 @@ public class Quantifier extends BoolExpr
**/
public boolean isExistential()
{
return !isUniversal();
return Native.isQuantifierExists(getContext().nCtx(), getNativeObject());
}
/**

View file

@ -1766,6 +1766,34 @@ class QuantifierRef(BoolRef):
"""
return Z3_is_quantifier_forall(self.ctx_ref(), self.ast)
def is_exists(self):
"""Return `True` if `self` is an existential quantifier.
>>> f = Function('f', IntSort(), IntSort())
>>> x = Int('x')
>>> q = ForAll(x, f(x) == 0)
>>> q.is_exists()
False
>>> q = Exists(x, f(x) != 0)
>>> q.is_exists()
True
"""
return Z3_is_quantifier_exists(self.ctx_ref(), self.ast)
def is_lambda(self):
"""Return `True` if `self` is a lambda expression.
>>> f = Function('f', IntSort(), IntSort())
>>> x = Int('x')
>>> q = Lambda(x, f(x))
>>> q.is_lambda()
True
>>> q = Exists(x, f(x) != 0)
>>> q.is_lambda()
False
"""
return Z3_is_lambda(self.ctx_ref(), self.ast)
def weight(self):
"""Return the weight annotation of `self`.
@ -1973,6 +2001,26 @@ def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
"""
return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns)
def Lambda(vs, body):
"""Create a Z3 lambda expression.
>>> f = Function('f', IntSort(), IntSort(), IntSort())
>>> mem0 = Array('mem0', IntSort(), IntSort())
>>> lo, hi, e, i = Ints('lo hi e i')
>>> mem1 = Lambda([i], If(And(lo <= i, i <= hi), e, mem0[i]))
>>> mem1
Lambda(i, If(And(lo <= i, i <= hi), e, mem0[i]))
"""
ctx = body.ctx
if is_app(vs):
vs = [vs]
num_vars = len(vs)
_vs = (Ast * num_vars)()
for i in range(num_vars):
## TODO: Check if is constant
_vs[i] = vs[i].as_ast()
return QuantifierRef(Z3_mk_lambda_const(ctx.ref(), num_vars, _vs, body.as_ast()), ctx)
#########################################
#
# Arithmetic
@ -5582,7 +5630,7 @@ class FuncEntry:
>>> m = s.model()
>>> f_i = m[f]
>>> f_i.num_entries()
3
1
>>> e = f_i.entry(0)
>>> e.num_args()
2
@ -5600,16 +5648,16 @@ class FuncEntry:
>>> m = s.model()
>>> f_i = m[f]
>>> f_i.num_entries()
3
1
>>> e = f_i.entry(0)
>>> e
[0, 1, 10]
[1, 2, 20]
>>> e.num_args()
2
>>> e.arg_value(0)
0
>>> e.arg_value(1)
1
>>> e.arg_value(1)
2
>>> try:
... e.arg_value(2)
... except IndexError:
@ -5631,14 +5679,14 @@ class FuncEntry:
>>> m = s.model()
>>> f_i = m[f]
>>> f_i.num_entries()
3
1
>>> e = f_i.entry(0)
>>> e
[0, 1, 10]
[1, 2, 20]
>>> e.num_args()
2
>>> e.value()
10
20
"""
return _to_expr_ref(Z3_func_entry_get_value(self.ctx.ref(), self.entry), self.ctx)
@ -5652,10 +5700,10 @@ class FuncEntry:
>>> m = s.model()
>>> f_i = m[f]
>>> f_i.num_entries()
3
1
>>> e = f_i.entry(0)
>>> e.as_list()
[0, 1, 10]
[1, 2, 20]
"""
args = [ self.arg_value(i) for i in range(self.num_args())]
args.append(self.value())
@ -5693,7 +5741,7 @@ class FuncInterp(Z3PPObject):
sat
>>> m = s.model()
>>> m[f]
[0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
[2 -> 0, else -> 1]
>>> m[f].else_value()
1
"""
@ -5713,9 +5761,9 @@ class FuncInterp(Z3PPObject):
sat
>>> m = s.model()
>>> m[f]
[0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
[2 -> 0, else -> 1]
>>> m[f].num_entries()
3
1
"""
return int(Z3_func_interp_get_num_entries(self.ctx.ref(), self.f))
@ -5743,14 +5791,10 @@ class FuncInterp(Z3PPObject):
sat
>>> m = s.model()
>>> m[f]
[0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
[2 -> 0, else -> 1]
>>> m[f].num_entries()
3
1
>>> m[f].entry(0)
[0, 1]
>>> m[f].entry(1)
[1, 1]
>>> m[f].entry(2)
[2, 0]
"""
if idx >= self.num_entries():
@ -5777,9 +5821,9 @@ class FuncInterp(Z3PPObject):
sat
>>> m = s.model()
>>> m[f]
[0 -> 1, 1 -> 1, 2 -> 0, else -> 1]
[2 -> 0, else -> 1]
>>> m[f].as_list()
[[0, 1], [1, 1], [2, 0], 1]
[[2, 0], 1]
"""
r = [ self.entry(i).as_list() for i in range(self.num_entries())]
r.append(self.else_value())
@ -5891,7 +5935,7 @@ class ModelRef(Z3PPObject):
>>> m[x]
1
>>> m[f]
[1 -> 0, else -> 0]
[else -> 0]
"""
if __debug__:
_z3_assert(isinstance(decl, FuncDeclRef) or is_const(decl), "Z3 declaration expected")
@ -6008,10 +6052,10 @@ class ModelRef(Z3PPObject):
>>> m[x]
1
>>> m[f]
[1 -> 0, else -> 0]
[else -> 0]
>>> for d in m: print("%s -> %s" % (d, m[d]))
x -> 1
f -> [1 -> 0, else -> 0]
f -> [else -> 0]
"""
if _is_int(idx):
if idx >= len(self):
@ -8351,11 +8395,6 @@ def _dict2darray(decls, ctx):
i = i + 1
return sz, _names, _decls
def _handle_parse_error(ex, ctx):
msg = Z3_get_parser_error(ctx.ref())
if msg != "":
raise Z3Exception(msg)
raise ex
def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
"""Parse a string in SMT 2.0 format using the given sorts and decls.
@ -8375,10 +8414,7 @@ def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
ctx = _get_ctx(ctx)
ssz, snames, ssorts = _dict2sarray(sorts, ctx)
dsz, dnames, ddecls = _dict2darray(decls, ctx)
try:
return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
except Z3Exception as e:
_handle_parse_error(e, ctx)
return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
"""Parse a file in SMT 2.0 format using the given sorts and decls.
@ -8388,10 +8424,7 @@ def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
ctx = _get_ctx(ctx)
ssz, snames, ssorts = _dict2sarray(sorts, ctx)
dsz, dnames, ddecls = _dict2darray(decls, ctx)
try:
return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
except Z3Exception as e:
_handle_parse_error(e, ctx)
return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
#########################################

View file

@ -959,8 +959,10 @@ class Formatter:
ys_pp = seq3(ys, '[', ']')
if a.is_forall():
header = 'ForAll'
else:
elif a.is_exists():
header = 'Exists'
else:
header = 'Lambda'
return seq1(header, (ys_pp, body_pp))
def pp_expr(self, a, d, xs):

View file

@ -482,6 +482,10 @@ typedef enum
T1: (~ p q)
[quant-intro T1]: (~ (forall (x) p) (forall (x) q))
- Z3_OP_PR_BIND: Given a proof p, produces a proof of lambda x . p, where x are free variables in p.
T1: f
[proof-bind T1] forall (x) f
- Z3_OP_PR_DISTRIBUTIVITY: Distributivity proof object.
Given that f (= or) distributes over g (= and), produces a proof for
@ -1109,6 +1113,7 @@ typedef enum {
Z3_OP_PR_TRANSITIVITY_STAR,
Z3_OP_PR_MONOTONICITY,
Z3_OP_PR_QUANT_INTRO,
Z3_OP_PR_BIND,
Z3_OP_PR_DISTRIBUTIVITY,
Z3_OP_PR_AND_ELIM,
Z3_OP_PR_NOT_OR_ELIM,
@ -1857,7 +1862,6 @@ extern "C" {
*/
Z3_sort Z3_API Z3_mk_array_sort_n(Z3_context c, unsigned n, Z3_sort const * domain, Z3_sort range);
/**
\brief Create a tuple type.
@ -2946,6 +2950,8 @@ extern "C" {
*/
Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i);
/**
\brief n-ary Array read.
The argument \c a is the array and \c idxs are the indices of the array that gets read.
@ -2955,6 +2961,7 @@ extern "C" {
*/
Z3_ast Z3_API Z3_mk_select_n(Z3_context c, Z3_ast a, unsigned n, Z3_ast const* idxs);
/**
\brief Array update.
@ -2973,6 +2980,7 @@ extern "C" {
*/
Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v);
/**
\brief n-ary Array update.
@ -3763,6 +3771,54 @@ extern "C" {
Z3_ast body
);
/**
\brief Create a lambda expression. It taks an expression \c body that contains bound variables
of the same sorts as the sorts listed in the array \c sorts. The bound variables are de-Bruijn indices created
using #Z3_mk_bound. The array \c decl_names contains the names that the quantified formula uses for the
bound variables. Z3 applies the convention that the last element in the \c decl_names and \c sorts array
refers to the variable with index 0, the second to last element of \c decl_names and \c sorts refers
to the variable with index 1, etc.
The sort of the resulting expression is \c (Array sorts range) where \c range is the sort of \c body.
For example, if the lambda binds two variables of sort \c Int and \c Bool, and the \c body has sort \c Real,
the sort of the expression is \c (Array Int Bool Real).
\param c logical context
\param num_decls number of variables to be bound.
\param sorts the sorts of the bound variables.
\param decl_names names of the bound variables
\param body the body of the lambda expression.
\sa Z3_mk_bound
\sa Z3_mk_forall
\sa Z3_mk_lambda_const
def_API('Z3_mk_lambda', AST, (_in(CONTEXT), _in(UINT), _in_array(1, SORT), _in_array(1, SYMBOL), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_lambda(Z3_context c,
unsigned num_decls, Z3_sort const sorts[],
Z3_symbol const decl_names[],
Z3_ast body);
/**
\brief Create a lambda expression using a list of constants that form the set
of bound variables
\param c logical context.
\param num_bound number of constants to be abstracted into bound variables.
\param bound array of constants to be abstracted into bound variables.
\param body the body of the lambda expression.
\sa Z3_mk_bound
\sa Z3_mk_forall
\sa Z3_mk_lambda
def_API('Z3_mk_lambda_const', AST, (_in(CONTEXT), _in(UINT), _in_array(1, APP), _in(AST)))
*/
Z3_ast Z3_API Z3_mk_lambda_const(Z3_context c,
unsigned num_bound, Z3_app const bound[],
Z3_ast body);
/*@}*/
/** @name Accessors */
@ -4529,14 +4585,29 @@ extern "C" {
unsigned Z3_API Z3_get_index_value(Z3_context c, Z3_ast a);
/**
\brief Determine if quantifier is universal.
\pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST
\brief Determine if an ast is a universal quantifier.
def_API('Z3_is_quantifier_forall', BOOL, (_in(CONTEXT), _in(AST)))
*/
Z3_bool Z3_API Z3_is_quantifier_forall(Z3_context c, Z3_ast a);
/**
\brief Determine if ast is an existential quantifier.
def_API('Z3_is_quantifier_exists', BOOL, (_in(CONTEXT), _in(AST)))
*/
Z3_bool Z3_API Z3_is_quantifier_exists(Z3_context c, Z3_ast a);
/**
\brief Determine if ast is a lambda expresion.
\pre Z3_get_ast_kind(a) == Z3_QUANTIFIER_AST
def_API('Z3_is_lambda', BOOL, (_in(CONTEXT), _in(AST)))
*/
Z3_bool Z3_API Z3_is_lambda(Z3_context c, Z3_ast a);
/**
\brief Obtain weight of quantifier.
@ -5209,12 +5280,6 @@ extern "C" {
Z3_string Z3_API Z3_eval_smtlib2_string(Z3_context, Z3_string str);
/**
\brief Retrieve that last error message information generated from parsing.
def_API('Z3_get_parser_error', STRING, (_in(CONTEXT), ))
*/
Z3_string Z3_API Z3_get_parser_error(Z3_context c);
/*@}*/
/** @name Error Handling */
@ -5261,11 +5326,6 @@ extern "C" {
*/
Z3_string Z3_API Z3_get_error_msg(Z3_context c, Z3_error_code err);
/**
\brief Return a string describing the given error code.
Retained function name for backwards compatibility within v4.1
*/
Z3_string Z3_API Z3_get_error_msg_ex(Z3_context c, Z3_error_code err);
/*@}*/
/** @name Miscellaneous */
@ -5465,6 +5525,11 @@ extern "C" {
/**
\brief Convert a goal into a DIMACS formatted string.
The goal must be in CNF. You can convert a goal to CNF
by applying the tseitin-cnf tactic. Bit-vectors are not automatically
converted to Booleans either, so the caller intends to
preserve satisfiability, it should apply bit-blasting tactics.
Quantifiers and theory atoms will not be encoded.
def_API('Z3_goal_to_dimacs_string', STRING, (_in(CONTEXT), _in(GOAL)))
*/

View file

@ -49,7 +49,7 @@ void __declspec(noinline) _Z3_append_log(char const * msg) { *g_z3_log << "M \""
static std::ostream & operator<<(std::ostream & out, ll_escaped const & d) {
char const * s = d.m_str;
while (*s) {
char c = *s;
unsigned char c = *s;
if (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') ||
c == '~' || c == '!' || c == '@' || c == '#' || c == '$' || c == '%' || c == '^' || c == '&' ||
c == '*' || c == '-' || c == '_' || c == '+' || c == '.' || c == '?' || c == '/' || c == ' ' ||
@ -57,7 +57,7 @@ static std::ostream & operator<<(std::ostream & out, ll_escaped const & d) {
out << c;
}
else {
char str[4] = {'0', '0', '0', 0};
unsigned char str[4] = {'0', '0', '0', 0};
str[2] = '0' + (c % 10);
c /= 10;
str[1] = '0' + (c % 10);

View file

@ -638,6 +638,11 @@ bool arith_recognizers::is_numeral(expr const * n, rational & val, bool & is_int
return true;
}
bool arith_recognizers::is_irrational_algebraic_numeral(expr const * n) const {
return is_app(n) && to_app(n)->is_app_of(m_afid, OP_IRRATIONAL_ALGEBRAIC_NUM);
}
#define IS_INT_EXPR_DEPTH_LIMIT 100
bool arith_recognizers::is_int_expr(expr const *e) const {
if (is_int(e)) return true;
@ -678,7 +683,7 @@ void arith_util::init_plugin() {
m_plugin = static_cast<arith_decl_plugin*>(m_manager.get_plugin(m_afid));
}
bool arith_util::is_irrational_algebraic_numeral(expr const * n, algebraic_numbers::anum & val) {
bool arith_util::is_irrational_algebraic_numeral2(expr const * n, algebraic_numbers::anum & val) {
if (!is_app_of(n, m_afid, OP_IRRATIONAL_ALGEBRAIC_NUM))
return false;
am().set(val, to_irrational_algebraic_numeral(n));

View file

@ -229,7 +229,7 @@ public:
family_id get_family_id() const { return m_afid; }
bool is_arith_expr(expr const * n) const { return is_app(n) && to_app(n)->get_family_id() == m_afid; }
bool is_irrational_algebraic_numeral(expr const * n) const { return is_app_of(n, m_afid, OP_IRRATIONAL_ALGEBRAIC_NUM); }
bool is_irrational_algebraic_numeral(expr const * n) const;
bool is_numeral(expr const * n, rational & val, bool & is_int) const;
bool is_numeral(expr const * n, rational & val) const { bool is_int; return is_numeral(n, val, is_int); }
bool is_numeral(expr const * n) const { return is_app_of(n, m_afid, OP_NUM); }
@ -338,8 +338,7 @@ public:
return plugin().am();
}
bool is_irrational_algebraic_numeral(expr const * n) const { return is_app_of(n, m_afid, OP_IRRATIONAL_ALGEBRAIC_NUM); }
bool is_irrational_algebraic_numeral(expr const * n, algebraic_numbers::anum & val);
bool is_irrational_algebraic_numeral2(expr const * n, algebraic_numbers::anum & val);
algebraic_numbers::anum const & to_irrational_algebraic_numeral(expr const * n);
sort * mk_int() { return m_manager.mk_sort(m_afid, INT_SORT); }
@ -535,3 +534,4 @@ inline app_ref operator>(app_ref const& x, app_ref const& y) {
}
#endif /* ARITH_DECL_PLUGIN_H_ */

View file

@ -26,6 +26,9 @@ Revision History:
#include "util/string_buffer.h"
#include "ast/ast_util.h"
#include "ast/ast_smt2_pp.h"
#include "ast/array_decl_plugin.h"
#include "ast/ast_translation.h"
// -----------------------------------
//
@ -360,13 +363,14 @@ app::app(func_decl * decl, unsigned num_args, expr * const * args):
//
// -----------------------------------
quantifier::quantifier(bool forall, unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names, expr * body,
quantifier::quantifier(quantifier_kind k, unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names, expr * body, sort* s,
int weight, symbol const & qid, symbol const & skid, unsigned num_patterns, expr * const * patterns,
unsigned num_no_patterns, expr * const * no_patterns):
expr(AST_QUANTIFIER),
m_forall(forall),
m_kind(k),
m_num_decls(num_decls),
m_expr(body),
m_sort(s),
m_depth(::get_depth(body) + 1),
m_weight(weight),
m_has_unused_vars(true),
@ -385,6 +389,25 @@ quantifier::quantifier(bool forall, unsigned num_decls, sort * const * decl_sort
memcpy(const_cast<expr **>(get_no_patterns()), no_patterns, sizeof(expr *) * num_no_patterns);
}
quantifier::quantifier(unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names, expr * body, sort* s):
expr(AST_QUANTIFIER),
m_kind(lambda_k),
m_num_decls(num_decls),
m_expr(body),
m_sort(s),
m_depth(::get_depth(body) + 1),
m_weight(0),
m_has_unused_vars(true),
m_has_labels(::has_labels(body)),
m_qid(symbol()),
m_skid(symbol()),
m_num_patterns(0),
m_num_no_patterns(0) {
memcpy(const_cast<sort **>(get_decl_sorts()), decl_sorts, sizeof(sort *) * num_decls);
memcpy(const_cast<symbol*>(get_decl_names()), decl_names, sizeof(symbol) * num_decls);
}
// -----------------------------------
//
// Auxiliary functions
@ -392,21 +415,16 @@ quantifier::quantifier(bool forall, unsigned num_decls, sort * const * decl_sort
// -----------------------------------
sort * get_sort(expr const * n) {
while (true) {
switch(n->get_kind()) {
case AST_APP:
return to_app(n)->get_decl()->get_range();
case AST_VAR:
return to_var(n)->get_sort();
case AST_QUANTIFIER:
// The sort of the quantifier is the sort of the nested expression.
// This code assumes the given expression is well-sorted.
n = to_quantifier(n)->get_expr();
break;
default:
UNREACHABLE();
return nullptr;
}
switch(n->get_kind()) {
case AST_APP:
return to_app(n)->get_decl()->get_range();
case AST_VAR:
return to_var(n)->get_sort();
case AST_QUANTIFIER:
return to_quantifier(n)->get_sort();
default:
UNREACHABLE();
return 0;
}
}
@ -466,7 +484,7 @@ bool compare_nodes(ast const * n1, ast const * n2) {
to_var(n1)->get_sort() == to_var(n2)->get_sort();
case AST_QUANTIFIER:
return
to_quantifier(n1)->is_forall() == to_quantifier(n2)->is_forall() &&
to_quantifier(n1)->get_kind() == to_quantifier(n2)->get_kind() &&
to_quantifier(n1)->get_num_decls() == to_quantifier(n2)->get_num_decls() &&
compare_arrays(to_quantifier(n1)->get_decl_sorts(),
to_quantifier(n2)->get_decl_sorts(),
@ -566,7 +584,7 @@ unsigned get_node_hash(ast const * n) {
case AST_QUANTIFIER:
a = ast_array_hash(to_quantifier(n)->get_decl_sorts(),
to_quantifier(n)->get_num_decls(),
to_quantifier(n)->is_forall() ? 31 : 19);
to_quantifier(n)->get_kind() == forall_k ? 31 : 19);
b = to_quantifier(n)->get_num_patterns();
c = to_quantifier(n)->get_expr()->hash();
mix(a,b,c);
@ -689,7 +707,8 @@ bool basic_decl_plugin::check_proof_sorts(basic_op_kind k, unsigned arity, sort
for (unsigned i = 0; i < arity - 1; i++)
if (domain[i] != m_proof_sort)
return false;
return domain[arity-1] == m_bool_sort || domain[arity-1] == m_proof_sort;
#define is_array(_x_) true
return domain[arity-1] == m_bool_sort || domain[arity-1] == m_proof_sort || is_array(domain[arity-1]);
}
}
@ -704,7 +723,8 @@ bool basic_decl_plugin::check_proof_args(basic_op_kind k, unsigned num_args, exp
return false;
return
m_manager->get_sort(args[num_args - 1]) == m_bool_sort ||
m_manager->get_sort(args[num_args - 1]) == m_proof_sort;
m_manager->get_sort(args[num_args - 1]) == m_proof_sort ||
is_lambda(args[num_args-1]);
}
}
@ -818,6 +838,7 @@ func_decl * basic_decl_plugin::mk_proof_decl(basic_op_kind k, unsigned num_paren
case PR_TRANSITIVITY_STAR: return mk_proof_decl("trans*", k, num_parents, m_transitivity_star_decls);
case PR_MONOTONICITY: return mk_proof_decl("monotonicity", k, num_parents, m_monotonicity_decls);
case PR_QUANT_INTRO: return mk_proof_decl("quant-intro", k, 1, m_quant_intro_decl);
case PR_BIND: UNREACHABLE();
case PR_DISTRIBUTIVITY: return mk_proof_decl("distributivity", k, num_parents, m_distributivity_decls);
case PR_AND_ELIM: return mk_proof_decl("and-elim", k, 1, m_and_elim_decl);
case PR_NOT_OR_ELIM: return mk_proof_decl("not-or-elim", k, 1, m_not_or_elim_decl);
@ -1054,6 +1075,10 @@ func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
// eq and oeq must have at least two arguments, they can have more since they are chainable
case OP_EQ: return arity >= 2 ? mk_eq_decl_core("=", OP_EQ, join(arity, domain), m_eq_decls) : nullptr;
case OP_OEQ: return arity >= 2 ? mk_eq_decl_core("~", OP_OEQ, join(arity, domain), m_oeq_decls) : nullptr;
case PR_BIND: {
func_decl_info info(m_family_id, PR_BIND);
return m_manager->mk_func_decl(symbol("proof-bind"), arity, domain, m_proof_sort, info);
}
case OP_DISTINCT: {
func_decl_info info(m_family_id, OP_DISTINCT);
info.set_pairwise();
@ -1097,6 +1122,11 @@ func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
case OP_OEQ: return num_args >= 2 ? mk_eq_decl_core("~", OP_OEQ, join(num_args, args), m_oeq_decls) : nullptr;
case OP_DISTINCT:
return decl_plugin::mk_func_decl(k, num_parameters, parameters, num_args, args, range);
case PR_BIND: {
ptr_buffer<sort> sorts;
for (unsigned i = 0; i < num_args; ++i) sorts.push_back(m_manager->get_sort(args[i]));
return mk_func_decl(k, num_parameters, parameters, num_args, sorts.c_ptr(), range);
}
default:
break;
}
@ -1218,7 +1248,6 @@ func_decl * model_value_decl_plugin::mk_func_decl(decl_kind k, unsigned num_para
unsigned arity, sort * const * domain, sort * range) {
SASSERT(k == OP_MODEL_VALUE);
if (arity != 0 || num_parameters != 2 || !parameters[0].is_int() || !parameters[1].is_ast() || !is_sort(parameters[1].get_ast())) {
UNREACHABLE();
m_manager->raise_exception("invalid model value");
return nullptr;
}
@ -1290,7 +1319,8 @@ ast_manager::ast_manager(proof_gen_mode m, char const * trace_file, bool is_form
m_proof_mode(m),
m_trace_stream(nullptr),
m_trace_stream_owner(false),
m_rec_fun(":rec-fun") {
m_rec_fun(":rec-fun"),
m_lambda_def(":lambda-def") {
if (trace_file) {
m_trace_stream = alloc(std::fstream, trace_file, std::ios_base::out);
@ -1312,7 +1342,8 @@ ast_manager::ast_manager(proof_gen_mode m, std::fstream * trace_stream, bool is_
m_proof_mode(m),
m_trace_stream(trace_stream),
m_trace_stream_owner(false),
m_rec_fun(":rec-fun") {
m_rec_fun(":rec-fun"),
m_lambda_def(":lambda-def") {
if (!is_format_manager)
m_format_manager = alloc(ast_manager, PGM_DISABLED, trace_stream, true);
@ -1340,6 +1371,7 @@ void ast_manager::update_fresh_id(ast_manager const& m) {
m_fresh_id = std::max(m_fresh_id, m.m_fresh_id);
}
void ast_manager::init() {
m_int_real_coercions = true;
m_debug_ref_count = false;
@ -1508,7 +1540,6 @@ void ast_manager::raise_exception(char const * msg) {
throw ast_exception(msg);
}
#include "ast/ast_translation.h"
void ast_manager::copy_families_plugins(ast_manager const & from) {
TRACE("copy_families_plugins",
@ -1761,6 +1792,7 @@ ast * ast_manager::register_node_core(ast * n) {
case AST_QUANTIFIER:
inc_array_ref(to_quantifier(n)->get_num_decls(), to_quantifier(n)->get_decl_sorts());
inc_ref(to_quantifier(n)->get_expr());
inc_ref(to_quantifier(n)->get_sort());
inc_array_ref(to_quantifier(n)->get_num_patterns(), to_quantifier(n)->get_patterns());
inc_array_ref(to_quantifier(n)->get_num_no_patterns(), to_quantifier(n)->get_no_patterns());
break;
@ -1824,6 +1856,7 @@ void ast_manager::delete_node(ast * n) {
case AST_QUANTIFIER:
dec_array_ref(worklist, to_quantifier(n)->get_num_decls(), to_quantifier(n)->get_decl_sorts());
dec_ref(worklist, to_quantifier(n)->get_expr());
dec_ref(worklist, to_quantifier(n)->get_sort());
dec_array_ref(worklist, to_quantifier(n)->get_num_patterns(), to_quantifier(n)->get_patterns());
dec_array_ref(worklist, to_quantifier(n)->get_num_no_patterns(), to_quantifier(n)->get_no_patterns());
break;
@ -2338,7 +2371,7 @@ bool ast_manager::is_pattern(expr const * n, ptr_vector<expr> &args) {
}
quantifier * ast_manager::mk_quantifier(bool forall, unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names,
quantifier * ast_manager::mk_quantifier(quantifier_kind k, unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names,
expr * body, int weight , symbol const & qid, symbol const & skid,
unsigned num_patterns, expr * const * patterns,
unsigned num_no_patterns, expr * const * no_patterns) {
@ -2353,7 +2386,17 @@ quantifier * ast_manager::mk_quantifier(bool forall, unsigned num_decls, sort *
}});
unsigned sz = quantifier::get_obj_size(num_decls, num_patterns, num_no_patterns);
void * mem = allocate_node(sz);
quantifier * new_node = new (mem) quantifier(forall, num_decls, decl_sorts, decl_names, body,
sort* s = nullptr;
if (k == lambda_k) {
array_util autil(*this);
s = autil.mk_array_sort(num_decls, decl_sorts, ::get_sort(body));
}
else {
s = mk_bool_sort();
}
quantifier * new_node = new (mem) quantifier(k, num_decls, decl_sorts, decl_names, body, s,
weight, qid, skid, num_patterns, patterns,
num_no_patterns, no_patterns);
quantifier * r = register_node(new_node);
@ -2370,6 +2413,18 @@ quantifier * ast_manager::mk_quantifier(bool forall, unsigned num_decls, sort *
return r;
}
quantifier * ast_manager::mk_lambda(unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names, expr * body) {
SASSERT(body);
unsigned sz = quantifier::get_obj_size(num_decls, 0, 0);
void * mem = allocate_node(sz);
array_util autil(*this);
sort* s = autil.mk_array_sort(num_decls, decl_sorts, ::get_sort(body));
quantifier * new_node = new (mem) quantifier(num_decls, decl_sorts, decl_names, body, s);
quantifier * r = register_node(new_node);
return r;
}
// Return true if the patterns of q are the given ones.
static bool same_patterns(quantifier * q, unsigned num_patterns, expr * const * patterns) {
if (num_patterns != q->get_num_patterns())
@ -2393,7 +2448,7 @@ static bool same_no_patterns(quantifier * q, unsigned num_no_patterns, expr * co
quantifier * ast_manager::update_quantifier(quantifier * q, unsigned num_patterns, expr * const * patterns, expr * body) {
if (q->get_expr() == body && same_patterns(q, num_patterns, patterns))
return q;
return mk_quantifier(q->is_forall(),
return mk_quantifier(q->get_kind(),
q->get_num_decls(),
q->get_decl_sorts(),
q->get_decl_names(),
@ -2410,7 +2465,7 @@ quantifier * ast_manager::update_quantifier(quantifier * q, unsigned num_pattern
quantifier * ast_manager::update_quantifier(quantifier * q, unsigned num_patterns, expr * const * patterns, unsigned num_no_patterns, expr * const * no_patterns, expr * body) {
if (q->get_expr() == body && same_patterns(q, num_patterns, patterns) && same_no_patterns(q, num_no_patterns, no_patterns))
return q;
return mk_quantifier(q->is_forall(),
return mk_quantifier(q->get_kind(),
q->get_num_decls(),
q->get_decl_sorts(),
q->get_decl_names(),
@ -2427,7 +2482,7 @@ quantifier * ast_manager::update_quantifier(quantifier * q, unsigned num_pattern
quantifier * ast_manager::update_quantifier(quantifier * q, expr * body) {
if (q->get_expr() == body)
return q;
return mk_quantifier(q->is_forall(),
return mk_quantifier(q->get_kind(),
q->get_num_decls(),
q->get_decl_sorts(),
q->get_decl_names(),
@ -2445,7 +2500,7 @@ quantifier * ast_manager::update_quantifier_weight(quantifier * q, int w) {
if (q->get_weight() == w)
return q;
TRACE("update_quantifier_weight", tout << "#" << q->get_id() << " " << q->get_weight() << " -> " << w << "\n";);
return mk_quantifier(q->is_forall(),
return mk_quantifier(q->get_kind(),
q->get_num_decls(),
q->get_decl_sorts(),
q->get_decl_names(),
@ -2459,10 +2514,10 @@ quantifier * ast_manager::update_quantifier_weight(quantifier * q, int w) {
q->get_no_patterns());
}
quantifier * ast_manager::update_quantifier(quantifier * q, bool is_forall, expr * body) {
if (q->get_expr() == body && q->is_forall() == is_forall)
quantifier * ast_manager::update_quantifier(quantifier * q, quantifier_kind k, expr * body) {
if (q->get_expr() == body && q->get_kind() == k)
return q;
return mk_quantifier(is_forall,
return mk_quantifier(k,
q->get_num_decls(),
q->get_decl_sorts(),
q->get_decl_names(),
@ -2476,10 +2531,10 @@ quantifier * ast_manager::update_quantifier(quantifier * q, bool is_forall, expr
q->get_no_patterns());
}
quantifier * ast_manager::update_quantifier(quantifier * q, bool is_forall, unsigned num_patterns, expr * const * patterns, expr * body) {
if (q->get_expr() == body && q->is_forall() == is_forall && same_patterns(q, num_patterns, patterns))
quantifier * ast_manager::update_quantifier(quantifier * q, quantifier_kind k, unsigned num_patterns, expr * const * patterns, expr * body) {
if (q->get_expr() == body && q->get_kind() == k && same_patterns(q, num_patterns, patterns))
return q;
return mk_quantifier(is_forall,
return mk_quantifier(k,
q->get_num_decls(),
q->get_decl_sorts(),
q->get_decl_names(),
@ -2786,11 +2841,17 @@ proof * ast_manager::mk_oeq_congruence(app * f1, app * f2, unsigned num_proofs,
return mk_monotonicity(mk_func_decl(m_basic_family_id, OP_OEQ, 0, nullptr, 2, d), f1, f2, num_proofs, proofs);
}
proof * ast_manager::mk_bind_proof(quantifier * q, proof * p) {
expr* b = mk_lambda(q->get_num_decls(), q->get_decl_sorts(), q->get_decl_names(), p);
return mk_app(m_basic_family_id, PR_BIND, b);
}
proof * ast_manager::mk_quant_intro(quantifier * q1, quantifier * q2, proof * p) {
if (!p) return nullptr;
SASSERT(q1->get_num_decls() == q2->get_num_decls());
SASSERT(has_fact(p));
SASSERT(is_eq(get_fact(p)));
SASSERT(is_eq(get_fact(p)) || is_lambda(get_fact(p)));
return mk_app(m_basic_family_id, PR_QUANT_INTRO, p, mk_iff(q1, q2));
}
@ -2798,7 +2859,7 @@ proof * ast_manager::mk_oeq_quant_intro(quantifier * q1, quantifier * q2, proof
if (!p) return nullptr;
SASSERT(q1->get_num_decls() == q2->get_num_decls());
SASSERT(has_fact(p));
SASSERT(is_oeq(get_fact(p)));
SASSERT(is_oeq(get_fact(p)) || is_lambda(get_fact(p)));
return mk_app(m_basic_family_id, PR_QUANT_INTRO, p, mk_oeq(q1, q2));
}

View file

@ -793,11 +793,18 @@ public:
//
// -----------------------------------
enum quantifier_kind {
forall_k,
exists_k,
lambda_k
};
class quantifier : public expr {
friend class ast_manager;
bool m_forall;
quantifier_kind m_kind;
unsigned m_num_decls;
expr * m_expr;
sort * m_sort;
unsigned m_depth;
// extra fields
int m_weight;
@ -813,12 +820,18 @@ class quantifier : public expr {
return sizeof(quantifier) + num_decls * (sizeof(sort *) + sizeof(symbol)) + (num_patterns + num_no_patterns) * sizeof(expr*);
}
quantifier(bool forall, unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names, expr * body,
quantifier(quantifier_kind k, unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names, expr * body, sort* s,
int weight, symbol const & qid, symbol const & skid, unsigned num_patterns, expr * const * patterns,
unsigned num_no_patterns, expr * const * no_patterns);
quantifier(unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names, expr * body, sort* sort);
public:
bool is_forall() const { return m_forall; }
bool is_exists() const { return !m_forall; }
quantifier_kind get_kind() const { return m_kind; }
// bool is_forall() const { return m_kind == forall_k; }
// bool is_exists() const { return m_kind == exists_k; }
// bool is_lambda() const { return m_kind == lambda_k; }
unsigned get_num_decls() const { return m_num_decls; }
sort * const * get_decl_sorts() const { return reinterpret_cast<sort * const *>(m_patterns_decls); }
symbol const * get_decl_names() const { return reinterpret_cast<symbol const *>(get_decl_sorts() + m_num_decls); }
@ -826,6 +839,8 @@ public:
symbol const & get_decl_name(unsigned idx) const { return get_decl_names()[idx]; }
expr * get_expr() const { return m_expr; }
sort * get_sort() const { return m_sort; }
unsigned get_depth() const { return m_depth; }
int get_weight() const { return m_weight; }
@ -844,6 +859,7 @@ public:
void set_no_unused_vars() { m_has_unused_vars = false; }
bool has_labels() const { return m_has_labels; }
unsigned get_num_children() const { return 1 + get_num_patterns() + get_num_no_patterns(); }
expr * get_child(unsigned idx) const {
@ -871,8 +887,9 @@ inline bool is_app(ast const * n) { return n->get_kind() == AST_APP; }
inline bool is_var(ast const * n) { return n->get_kind() == AST_VAR; }
inline bool is_var(ast const * n, unsigned& idx) { return is_var(n) && (idx = static_cast<var const*>(n)->get_idx(), true); }
inline bool is_quantifier(ast const * n) { return n->get_kind() == AST_QUANTIFIER; }
inline bool is_forall(ast const * n) { return is_quantifier(n) && static_cast<quantifier const *>(n)->is_forall(); }
inline bool is_exists(ast const * n) { return is_quantifier(n) && static_cast<quantifier const *>(n)->is_exists(); }
inline bool is_forall(ast const * n) { return is_quantifier(n) && static_cast<quantifier const *>(n)->get_kind() == forall_k; }
inline bool is_exists(ast const * n) { return is_quantifier(n) && static_cast<quantifier const *>(n)->get_kind() == exists_k; }
inline bool is_lambda(ast const * n) { return is_quantifier(n) && static_cast<quantifier const *>(n)->get_kind() == lambda_k; }
// -----------------------------------
//
@ -950,7 +967,7 @@ protected:
family_id m_family_id;
virtual void set_manager(ast_manager * m, family_id id) {
SASSERT(m_manager == 0);
SASSERT(m_manager == nullptr);
m_manager = m;
m_family_id = id;
}
@ -1043,7 +1060,7 @@ enum basic_sort_kind {
enum basic_op_kind {
OP_TRUE, OP_FALSE, OP_EQ, OP_DISTINCT, OP_ITE, OP_AND, OP_OR, OP_XOR, OP_NOT, OP_IMPLIES, OP_OEQ, LAST_BASIC_OP,
PR_UNDEF, PR_TRUE, PR_ASSERTED, PR_GOAL, PR_MODUS_PONENS, PR_REFLEXIVITY, PR_SYMMETRY, PR_TRANSITIVITY, PR_TRANSITIVITY_STAR, PR_MONOTONICITY, PR_QUANT_INTRO,
PR_UNDEF, PR_TRUE, PR_ASSERTED, PR_GOAL, PR_MODUS_PONENS, PR_REFLEXIVITY, PR_SYMMETRY, PR_TRANSITIVITY, PR_TRANSITIVITY_STAR, PR_MONOTONICITY, PR_QUANT_INTRO, PR_BIND,
PR_DISTRIBUTIVITY, PR_AND_ELIM, PR_NOT_OR_ELIM, PR_REWRITE, PR_REWRITE_STAR, PR_PULL_QUANT,
PR_PUSH_QUANT, PR_ELIM_UNUSED_VARS, PR_DER, PR_QUANT_INST,
@ -1487,6 +1504,7 @@ protected:
#endif
ast_manager * m_format_manager; // hack for isolating format objects in a different manager.
symbol m_rec_fun;
symbol m_lambda_def;
void init();
@ -1594,9 +1612,12 @@ public:
bool contains(ast * a) const { return m_ast_table.contains(a); }
bool is_rec_fun_def(quantifier* q) const { return q->get_qid() == m_rec_fun; }
bool is_lambda_def(quantifier* q) const { return q->get_qid() == m_lambda_def; }
symbol const& rec_fun_qid() const { return m_rec_fun; }
symbol const& lambda_def_qid() const { return m_lambda_def; }
unsigned get_num_asts() const { return m_ast_table.size(); }
void debug_ref_count() { m_debug_ref_count = true; }
@ -1892,7 +1913,7 @@ public:
public:
quantifier * mk_quantifier(bool forall, unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names, expr * body,
quantifier * mk_quantifier(quantifier_kind k, unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names, expr * body,
int weight = 0, symbol const & qid = symbol::null, symbol const & skid = symbol::null,
unsigned num_patterns = 0, expr * const * patterns = nullptr,
unsigned num_no_patterns = 0, expr * const * no_patterns = nullptr);
@ -1901,7 +1922,7 @@ public:
int weight = 0, symbol const & qid = symbol::null, symbol const & skid = symbol::null,
unsigned num_patterns = 0, expr * const * patterns = nullptr,
unsigned num_no_patterns = 0, expr * const * no_patterns = nullptr) {
return mk_quantifier(true, num_decls, decl_sorts, decl_names, body, weight, qid, skid, num_patterns, patterns,
return mk_quantifier(forall_k, num_decls, decl_sorts, decl_names, body, weight, qid, skid, num_patterns, patterns,
num_no_patterns, no_patterns);
}
@ -1909,10 +1930,12 @@ public:
int weight = 0, symbol const & qid = symbol::null, symbol const & skid = symbol::null,
unsigned num_patterns = 0, expr * const * patterns = nullptr,
unsigned num_no_patterns = 0, expr * const * no_patterns = nullptr) {
return mk_quantifier(false, num_decls, decl_sorts, decl_names, body, weight, qid, skid, num_patterns, patterns,
return mk_quantifier(exists_k, num_decls, decl_sorts, decl_names, body, weight, qid, skid, num_patterns, patterns,
num_no_patterns, no_patterns);
}
quantifier * mk_lambda(unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names, expr * body);
quantifier * update_quantifier(quantifier * q, unsigned new_num_patterns, expr * const * new_patterns, expr * new_body);
quantifier * update_quantifier(quantifier * q, unsigned new_num_patterns, expr * const * new_patterns, unsigned new_num_no_patterns, expr * const * new_no_patterns, expr * new_body);
@ -1921,9 +1944,9 @@ public:
quantifier * update_quantifier_weight(quantifier * q, int new_weight);
quantifier * update_quantifier(quantifier * q, bool new_is_forall, expr * new_body);
quantifier * update_quantifier(quantifier * q, quantifier_kind new_kind, expr * new_body);
quantifier * update_quantifier(quantifier * q, bool new_is_forall, unsigned new_num_patterns, expr * const * new_patterns, expr * new_body);
quantifier * update_quantifier(quantifier * q, quantifier_kind new_kind, unsigned new_num_patterns, expr * const * new_patterns, expr * new_body);
// -----------------------------------
//
@ -2213,6 +2236,7 @@ public:
proof * mk_rewrite(expr * s, expr * t);
proof * mk_oeq_rewrite(expr * s, expr * t);
proof * mk_rewrite_star(expr * s, expr * t, unsigned num_proofs, proof * const * proofs);
proof * mk_bind_proof(quantifier * q, proof * p);
proof * mk_pull_quant(expr * e, quantifier * q);
proof * mk_push_quant(quantifier * q, expr * e);
proof * mk_elim_unused_vars(quantifier * q, expr * r);

View file

@ -242,7 +242,7 @@ public:
void operator()(quantifier * n) {
display_def_header(n);
m_out << "(" << (n->is_forall() ? "forall" : "exists") << " ";
m_out << "(" << (n->get_kind() == forall_k ? "forall" : (n->get_kind() == exists_k ? "exists" : "lambda")) << " ";
unsigned num_decls = n->get_num_decls();
m_out << "(vars ";
for (unsigned i = 0; i < num_decls; i++) {

View file

@ -102,7 +102,7 @@ bool lt(ast * n1, ast * n2) {
UNREACHABLE();
return false;
case AST_QUANTIFIER:
check_bool(to_quantifier(n1)->is_forall(), to_quantifier(n2)->is_forall());
check_value(to_quantifier(n1)->get_kind(), to_quantifier(n2)->get_kind());
check_value(to_quantifier(n1)->get_num_decls(), to_quantifier(n2)->get_num_decls());
check_value(to_quantifier(n1)->get_num_patterns(), to_quantifier(n2)->get_num_patterns());
check_value(to_quantifier(n1)->get_num_no_patterns(), to_quantifier(n2)->get_num_no_patterns());

View file

@ -994,7 +994,7 @@ class smt2_printer {
}
format * f_decls = pp_var_decls(q);
format * fs[2] = { f_decls, f_body };
char const * header = q->is_forall() ? "forall" : "exists";
char const * header = q->get_kind() == forall_k ? "forall" : (q->get_kind() == exists_k ? "exists" : "lambda");
format * f = mk_seq3<format**, f2f>(m(), fs, fs+2, f2f(), header, 1, SMALL_INDENT);
info f_info = m_info_stack.back();
@ -1041,6 +1041,10 @@ class smt2_printer {
}
void process(expr * n, format_ref & r) {
if (!n) {
r = mk_string(m(), "null");
return;
}
reset_stacks();
SASSERT(&(r.get_manager()) == &(fm()));
m_soccs(n);
@ -1126,6 +1130,10 @@ public:
}
void operator()(func_decl * f, format_ref & r, char const* cmd) {
if (!f) {
r = mk_string(m(), "null");
return;
}
unsigned arity = f->get_arity();
unsigned len;
format * fname = m_env.pp_fdecl_name(f, len);
@ -1189,15 +1197,16 @@ void mk_smt2_format(unsigned sz, expr * const* es, smt2_pp_environment & env, pa
format_ref_vector fmts(fm(m));
for (unsigned i = 0; i < sz; ++i) {
format_ref fr(fm(m));
format_ref fr(fm(m));
pr(es[i], num_vars, var_prefix, fr, var_names);
fmts.push_back(fr);
fmts.push_back(std::move(fr));
}
r = mk_seq<format**, f2f>(m, fmts.c_ptr(), fmts.c_ptr() + fmts.size(), f2f());
}
std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, params_ref const & p, unsigned indent,
unsigned num_vars, char const * var_prefix) {
if (!n) return out << "null";
ast_manager & m = env.get_manager();
format_ref r(fm(m));
sbuffer<symbol> var_names;
@ -1209,6 +1218,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & e
}
std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, params_ref const & p, unsigned indent) {
if (s == nullptr) return out << "null";
ast_manager & m = env.get_manager();
format_ref r(fm(m));
sbuffer<symbol> var_names;
@ -1220,6 +1230,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & e
}
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p, unsigned indent, char const* cmd) {
if (!f) return out << "null";
ast_manager & m = env.get_manager();
format_ref r(fm(m));
sbuffer<symbol> var_names;
@ -1231,6 +1242,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environmen
}
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p, unsigned indent, char const* cmd) {
if (!f) return out << "null";
ast_manager & m = env.get_manager();
format_ref r(fm(m));
sbuffer<symbol> var_names;

View file

@ -495,11 +495,10 @@ class smt_printer {
m_qlists.push_back(q);
m_out << "(";
if (q->is_forall()) {
m_out << "forall ";
}
else {
m_out << "exists ";
switch (q->get_kind()) {
case forall_k: m_out << "forall "; break;
case exists_k: m_out << "exists "; break;
case lambda_k: m_out << "lambda "; break;
}
m_out << "(";
for (unsigned i = 0; i < q->get_num_decls(); ++i) {

View file

@ -279,7 +279,7 @@ ast * ast_translation::process(ast const * _n) {
expr ** pats = reinterpret_cast<expr**>(m_result_stack.c_ptr() + fr.m_rpos + num_decls + 1);
unsigned num_no_pats = to_quantifier(n)->get_num_no_patterns();
expr ** no_pats = pats + num_pats;
quantifier * new_q = m_to_manager.mk_quantifier(to_quantifier(n)->is_forall(),
quantifier * new_q = m_to_manager.mk_quantifier(to_quantifier(n)->get_kind(),
num_decls,
dsorts,
dnames,

View file

@ -128,11 +128,9 @@ bool is_clause(ast_manager & m, expr * n) {
if (is_literal(m, n))
return true;
if (m.is_or(n)) {
unsigned num_args = to_app(n)->get_num_args();
for (unsigned i = 0; i < num_args; i++) {
if (!is_literal(m, to_app(n)->get_arg(i)))
return false;
}
for (expr* arg : *to_app(n))
if (!is_literal(m, arg))
return false;
return true;
}
return false;
@ -211,8 +209,8 @@ expr_ref push_not(const expr_ref& e) {
return expr_ref(m.mk_false(), m);
}
expr_ref_vector args(m);
for (unsigned i = 0; i < a->get_num_args(); ++i) {
args.push_back(push_not(expr_ref(a->get_arg(i), m)));
for (expr* arg : *a) {
args.push_back(push_not(expr_ref(arg, m)));
}
return mk_or(args);
}
@ -221,8 +219,8 @@ expr_ref push_not(const expr_ref& e) {
return expr_ref(m.mk_true(), m);
}
expr_ref_vector args(m);
for (unsigned i = 0; i < a->get_num_args(); ++i) {
args.push_back(push_not(expr_ref(a->get_arg(i), m)));
for (expr* arg : *a) {
args.push_back(push_not(expr_ref(arg, m)));
}
return mk_and(args);
}
@ -260,44 +258,38 @@ void flatten_and(expr_ref_vector& result) {
ast_manager& m = result.get_manager();
expr* e1, *e2, *e3;
for (unsigned i = 0; i < result.size(); ++i) {
if (m.is_and(result[i].get())) {
app* a = to_app(result[i].get());
unsigned num_args = a->get_num_args();
for (unsigned j = 0; j < num_args; ++j) {
result.push_back(a->get_arg(j));
}
if (m.is_and(result.get(i))) {
app* a = to_app(result.get(i));
for (expr* arg : *a) result.push_back(arg);
result[i] = result.back();
result.pop_back();
--i;
}
else if (m.is_not(result[i].get(), e1) && m.is_not(e1, e2)) {
else if (m.is_not(result.get(i), e1) && m.is_not(e1, e2)) {
result[i] = e2;
--i;
}
else if (m.is_not(result[i].get(), e1) && m.is_or(e1)) {
else if (m.is_not(result.get(i), e1) && m.is_or(e1)) {
app* a = to_app(e1);
unsigned num_args = a->get_num_args();
for (unsigned j = 0; j < num_args; ++j) {
result.push_back(m.mk_not(a->get_arg(j)));
}
for (expr* arg : *a) result.push_back(m.mk_not(arg));
result[i] = result.back();
result.pop_back();
--i;
}
else if (m.is_not(result[i].get(), e1) && m.is_implies(e1,e2,e3)) {
else if (m.is_not(result.get(i), e1) && m.is_implies(e1,e2,e3)) {
result.push_back(e2);
result[i] = m.mk_not(e3);
--i;
}
else if (m.is_true(result[i].get()) ||
(m.is_not(result[i].get(), e1) &&
else if (m.is_true(result.get(i)) ||
(m.is_not(result.get(i), e1) &&
m.is_false(e1))) {
result[i] = result.back();
result.pop_back();
--i;
}
else if (m.is_false(result[i].get()) ||
(m.is_not(result[i].get(), e1) &&
else if (m.is_false(result.get(i)) ||
(m.is_not(result.get(i), e1) &&
m.is_true(e1))) {
result.reset();
result.push_back(m.mk_false());
@ -323,44 +315,38 @@ void flatten_or(expr_ref_vector& result) {
ast_manager& m = result.get_manager();
expr* e1, *e2, *e3;
for (unsigned i = 0; i < result.size(); ++i) {
if (m.is_or(result[i].get())) {
app* a = to_app(result[i].get());
unsigned num_args = a->get_num_args();
for (unsigned j = 0; j < num_args; ++j) {
result.push_back(a->get_arg(j));
}
if (m.is_or(result.get(i))) {
app* a = to_app(result.get(i));
for (expr* arg : *a) result.push_back(arg);
result[i] = result.back();
result.pop_back();
--i;
}
else if (m.is_not(result[i].get(), e1) && m.is_not(e1, e2)) {
else if (m.is_not(result.get(i), e1) && m.is_not(e1, e2)) {
result[i] = e2;
--i;
}
else if (m.is_not(result[i].get(), e1) && m.is_and(e1)) {
else if (m.is_not(result.get(i), e1) && m.is_and(e1)) {
app* a = to_app(e1);
unsigned num_args = a->get_num_args();
for (unsigned j = 0; j < num_args; ++j) {
result.push_back(m.mk_not(a->get_arg(j)));
}
for (expr* arg : *a) result.push_back(m.mk_not(arg));
result[i] = result.back();
result.pop_back();
--i;
}
else if (m.is_implies(result[i].get(),e2,e3)) {
else if (m.is_implies(result.get(i),e2,e3)) {
result.push_back(e3);
result[i] = m.mk_not(e2);
--i;
}
else if (m.is_false(result[i].get()) ||
(m.is_not(result[i].get(), e1) &&
else if (m.is_false(result.get(i)) ||
(m.is_not(result.get(i), e1) &&
m.is_true(e1))) {
result[i] = result.back();
result.pop_back();
--i;
}
else if (m.is_true(result[i].get()) ||
(m.is_not(result[i].get(), e1) &&
else if (m.is_true(result.get(i)) ||
(m.is_not(result.get(i), e1) &&
m.is_false(e1))) {
result.reset();
result.push_back(m.mk_true());

View file

@ -354,6 +354,8 @@ public:
MATCH_BINARY(is_bv_mul);
MATCH_BINARY(is_bv_sle);
MATCH_BINARY(is_bv_ule);
MATCH_BINARY(is_bv_ashr);
MATCH_BINARY(is_bv_lshr);
MATCH_BINARY(is_bv_shl);
MATCH_BINARY(is_bv_urem);
MATCH_BINARY(is_bv_srem);

View file

@ -115,7 +115,7 @@ void expr_abstract(ast_manager& m, unsigned base, unsigned num_bound, expr* cons
tout << result << "\n";);
}
expr_ref mk_quantifier(bool is_forall, ast_manager& m, unsigned num_bound, app* const* bound, expr* n) {
expr_ref mk_quantifier(quantifier_kind k, ast_manager& m, unsigned num_bound, app* const* bound, expr* n) {
expr_ref result(m);
expr_abstract(m, 0, num_bound, (expr* const*)bound, n, result);
if (num_bound > 0) {
@ -125,7 +125,7 @@ expr_ref mk_quantifier(bool is_forall, ast_manager& m, unsigned num_bound, app*
sorts.push_back(m.get_sort(bound[i]));
names.push_back(bound[i]->get_decl()->get_name());
}
result = m.mk_quantifier(is_forall, num_bound, sorts.c_ptr(), names.c_ptr(), result);
result = m.mk_quantifier(k, num_bound, sorts.c_ptr(), names.c_ptr(), result);
}
TRACE("expr_abstract",
tout << expr_ref(n, m) << "\n";
@ -137,9 +137,9 @@ expr_ref mk_quantifier(bool is_forall, ast_manager& m, unsigned num_bound, app*
}
expr_ref mk_forall(ast_manager& m, unsigned num_bound, app* const* bound, expr* n) {
return mk_quantifier(true, m, num_bound, bound, n);
return mk_quantifier(forall_k, m, num_bound, bound, n);
}
expr_ref mk_exists(ast_manager& m, unsigned num_bound, app* const* bound, expr* n) {
return mk_quantifier(false, m, num_bound, bound, n);
return mk_quantifier(exists_k, m, num_bound, bound, n);
}

View file

@ -3108,12 +3108,12 @@ void fpa2bv_converter::mk_to_ieee_bv_unspecified(func_decl * f, unsigned num, ex
expr_ref exp_bv(m), exp_all_ones(m);
exp_bv = m_bv_util.mk_extract(ebits+sbits-2, sbits-1, result);
exp_all_ones = m.mk_eq(exp_bv, m_bv_util.mk_bv_neg(m_bv_util.mk_numeral(1, ebits)));
m_extra_assertions.push_back(exp_all_ones);
m_extra_assertions.push_back(std::move(exp_all_ones));
expr_ref sig_bv(m), sig_is_non_zero(m);
sig_bv = m_bv_util.mk_extract(sbits-2, 0, result);
sig_is_non_zero = m.mk_not(m.mk_eq(sig_bv, m_bv_util.mk_numeral(0, sbits-1)));
m_extra_assertions.push_back(sig_is_non_zero);
m_extra_assertions.push_back(std::move(sig_is_non_zero));
}
TRACE("fpa2bv_to_ieee_bv_unspecified", tout << "result=" << mk_ismt2_pp(result, m) << std::endl;);

View file

@ -194,6 +194,9 @@ bool fpa2bv_rewriter_cfg::reduce_quantifier(quantifier * old_q,
expr * const * new_no_patterns,
expr_ref & result,
proof_ref & result_pr) {
if (is_lambda(old_q)) {
return false;
}
unsigned curr_sz = m_bindings.size();
SASSERT(old_q->get_num_decls() <= curr_sz);
unsigned num_decls = old_q->get_num_decls();
@ -217,7 +220,7 @@ bool fpa2bv_rewriter_cfg::reduce_quantifier(quantifier * old_q,
new_decl_names.push_back(n);
}
}
result = m().mk_quantifier(old_q->is_forall(), new_decl_sorts.size(), new_decl_sorts.c_ptr(), new_decl_names.c_ptr(),
result = m().mk_quantifier(old_q->get_kind(), new_decl_sorts.size(), new_decl_sorts.c_ptr(), new_decl_names.c_ptr(),
new_body, old_q->get_weight(), old_q->get_qid(), old_q->get_skid(),
old_q->get_num_patterns(), new_patterns, old_q->get_num_no_patterns(), new_no_patterns);
result_pr = nullptr;

View file

@ -23,7 +23,7 @@ Revision History:
#include "ast/ast_ll_pp.h"
bool macro_finder::is_macro(expr * n, app_ref & head, expr_ref & def) {
if (!is_quantifier(n) || !to_quantifier(n)->is_forall())
if (!is_forall(n))
return false;
TRACE("macro_finder", tout << "processing: " << mk_pp(n, m) << "\n";);
expr * body = to_quantifier(n)->get_expr();
@ -46,7 +46,7 @@ bool macro_finder::is_macro(expr * n, app_ref & head, expr_ref & def) {
For case 2 & 3, the new quantifiers are stored in new_exprs and new_prs.
*/
bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_dependency * dep, expr_ref_vector & new_exprs, proof_ref_vector & new_prs, expr_dependency_ref_vector & new_deps) {
if (!is_quantifier(n) || !to_quantifier(n)->is_forall())
if (!is_forall(n))
return false;
expr * body = to_quantifier(n)->get_expr();
unsigned num_decls = to_quantifier(n)->get_num_decls();
@ -117,7 +117,7 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, expr_dependency * dep, e
}
bool macro_finder::is_arith_macro(expr * n, proof * pr, vector<justified_expr>& new_fmls) {
if (!is_quantifier(n) || !to_quantifier(n)->is_forall())
if (!is_forall(n))
return false;
expr * body = to_quantifier(n)->get_expr();
unsigned num_decls = to_quantifier(n)->get_num_decls();

View file

@ -283,13 +283,11 @@ struct macro_manager::macro_expander_cfg : public default_rewriter_cfg {
subst_args[nidx] = n->get_arg(i);
}
var_subst s(m);
expr_ref rr(m);
s(def, num, subst_args.c_ptr(), rr);
expr_ref rr = s(def, num, subst_args.c_ptr());
m_trail.push_back(rr);
r = rr;
if (m.proofs_enabled()) {
expr_ref instance(m);
s(q->get_expr(), num, subst_args.c_ptr(), instance);
expr_ref instance = s(q->get_expr(), num, subst_args.c_ptr());
proof * qi_pr = m.mk_quant_inst(m.mk_or(m.mk_not(q), instance), num, subst_args.c_ptr());
proof * q_pr = nullptr;
mm.m_decl2macro_pr.find(d, q_pr);

View file

@ -334,7 +334,7 @@ bool macro_util::is_pseudo_head(expr * n, unsigned num_decls, app_ref & head, ap
where t is a ground term, (f X) is the head.
*/
bool macro_util::is_pseudo_predicate_macro(expr * n, app_ref & head, app_ref & t, expr_ref & def) {
if (!is_quantifier(n) || !to_quantifier(n)->is_forall())
if (!is_forall(n))
return false;
TRACE("macro_util", tout << "processing: " << mk_pp(n, m_manager) << "\n";);
expr * body = to_quantifier(n)->get_expr();
@ -485,7 +485,7 @@ void macro_util::normalize_expr(app * head, unsigned num_decls, expr * t, expr_r
if (var_mapping[i] != 0)
tout << "#" << i << " -> " << mk_ll_pp(var_mapping[i], m_manager);
});
subst(t, var_mapping.size(), var_mapping.c_ptr(), norm_t);
norm_t = subst(t, var_mapping.size(), var_mapping.c_ptr());
}
else {
norm_t = t;

View file

@ -155,7 +155,7 @@ bool quasi_macros::is_quasi_macro(expr * e, app_ref & a, expr_ref & t) const {
// f[X] contains all universally quantified variables, and f does not occur in T[X].
TRACE("quasi_macros", tout << "Checking for quasi macro: " << mk_pp(e, m_manager) << std::endl;);
if (is_quantifier(e) && to_quantifier(e)->is_forall()) {
if (is_forall(e)) {
quantifier * q = to_quantifier(e);
expr * qe = q->get_expr();
if ((m_manager.is_eq(qe))) {
@ -251,7 +251,7 @@ void quasi_macros::quasi_macro_to_macro(quantifier * q, app * a, expr * t, quant
eq = m_manager.mk_eq(appl, ite);
macro = m_manager.mk_quantifier(true, new_var_names_rev.size(),
macro = m_manager.mk_quantifier(forall_k, new_var_names_rev.size(),
new_qsorts_rev.c_ptr(), new_var_names_rev.c_ptr(), eq);
}

View file

@ -16,17 +16,19 @@ Author:
Revision History:
--*/
#include "ast/normal_forms/defined_names.h"
#include "util/obj_hashtable.h"
#include "ast/normal_forms/defined_names.h"
#include "ast/used_vars.h"
#include "ast/rewriter/var_subst.h"
#include "ast/ast_smt2_pp.h"
#include "ast/ast_pp.h"
#include "ast/ast_util.h"
#include "ast/array_decl_plugin.h"
struct defined_names::impl {
typedef obj_map<expr, app *> expr2name;
typedef obj_map<expr, proof *> expr2proof;
ast_manager & m_manager;
ast_manager & m;
symbol m_z3name;
/**
@ -60,9 +62,9 @@ struct defined_names::impl {
app * gen_name(expr * e, sort_ref_buffer & var_sorts, buffer<symbol> & var_names);
void cache_new_name(expr * e, app * name);
void cache_new_name_intro_proof(expr * e, proof * pr);
void bound_vars(sort_ref_buffer const & sorts, buffer<symbol> const & names, expr * def_conjunct, app * name, expr_ref & result);
void bound_vars(sort_ref_buffer const & sorts, buffer<symbol> const & names, expr * def_conjunct, app * name, expr_ref_buffer & result);
virtual void mk_definition(expr * e, app * n, sort_ref_buffer & var_sorts, buffer<symbol> const & var_names, expr_ref & new_def);
void bound_vars(sort_ref_buffer const & sorts, buffer<symbol> const & names, expr * def_conjunct, app * name, expr_ref & result, symbol const& qid = symbol::null);
void bound_vars(sort_ref_buffer const & sorts, buffer<symbol> const & names, expr * def_conjunct, app * name, expr_ref_buffer & result, symbol const& qid = symbol::null);
virtual void mk_definition(expr * e, app * n, sort_ref_buffer & var_sorts, buffer<symbol> & var_names, expr_ref & new_def);
bool mk_name(expr * e, expr_ref & new_def, proof_ref & new_def_pr, app_ref & n, proof_ref & pr);
void push_scope();
void pop_scope(unsigned num_scopes);
@ -74,12 +76,13 @@ struct defined_names::impl {
struct defined_names::pos_impl : public defined_names::impl {
pos_impl(ast_manager & m, char const * fresh_prefix):impl(m, fresh_prefix) {}
void mk_definition(expr * e, app * n, sort_ref_buffer & var_sorts, buffer<symbol> const & var_names, expr_ref & new_def) override;
void mk_definition(expr * e, app * n, sort_ref_buffer & var_sorts, buffer<symbol> & var_names, expr_ref & new_def) override;
};
defined_names::impl::impl(ast_manager & m, char const * prefix):
m_manager(m),
m(m),
m_exprs(m),
m_names(m),
m_apply_proofs(m) {
@ -107,20 +110,20 @@ app * defined_names::impl::gen_name(expr * e, sort_ref_buffer & var_sorts, buffe
sort * s = uv.get(i);
if (s) {
domain.push_back(s);
new_args.push_back(m_manager.mk_var(i, s));
new_args.push_back(m.mk_var(i, s));
var_sorts.push_back(s);
}
else {
var_sorts.push_back(m_manager.mk_bool_sort()); // could be any sort.
var_sorts.push_back(m.mk_bool_sort()); // could be any sort.
}
var_names.push_back(symbol(i));
}
sort * range = m_manager.get_sort(e);
func_decl * new_skolem_decl = m_manager.mk_fresh_func_decl(m_z3name, symbol::null, domain.size(), domain.c_ptr(), range);
app * n = m_manager.mk_app(new_skolem_decl, new_args.size(), new_args.c_ptr());
TRACE("mk_definition_bug", tout << "gen_name: " << mk_ismt2_pp(n, m_manager) << "\n";
for (unsigned i = 0; i < var_sorts.size(); i++) tout << mk_pp(var_sorts[i], m_manager) << " ";
sort * range = m.get_sort(e);
func_decl * new_skolem_decl = m.mk_fresh_func_decl(m_z3name, symbol::null, domain.size(), domain.c_ptr(), range);
app * n = m.mk_app(new_skolem_decl, new_args.size(), new_args.c_ptr());
TRACE("mk_definition_bug", tout << "gen_name: " << mk_ismt2_pp(n, m) << "\n";
for (unsigned i = 0; i < var_sorts.size(); i++) tout << mk_pp(var_sorts[i], m) << " ";
tout << "\n";);
return n;
}
@ -148,22 +151,22 @@ void defined_names::impl::cache_new_name_intro_proof(expr * e, proof * pr) {
A quantifier is added around \c def_conjunct, if sorts and names are not empty.
In this case, The application \c name is used as a pattern for the new quantifier.
*/
void defined_names::impl::bound_vars(sort_ref_buffer const & sorts, buffer<symbol> const & names, expr * def_conjunct, app * name, expr_ref & result) {
void defined_names::impl::bound_vars(sort_ref_buffer const & sorts, buffer<symbol> const & names, expr * def_conjunct, app * name, expr_ref & result, symbol const& qid) {
SASSERT(sorts.size() == names.size());
if (sorts.empty())
result = def_conjunct;
else {
expr * patterns[1] = { m_manager.mk_pattern(name) };
quantifier_ref q(m_manager);
q = m_manager.mk_forall(sorts.size(),
expr * patterns[1] = { m.mk_pattern(name) };
quantifier_ref q(m);
q = m.mk_forall(sorts.size(),
sorts.c_ptr(),
names.c_ptr(),
def_conjunct,
1, symbol::null, symbol::null,
1, qid, symbol::null,
1, patterns);
TRACE("mk_definition_bug", tout << "before elim_unused_vars:\n" << mk_ismt2_pp(q, m_manager) << "\n";);
elim_unused_vars(m_manager, q, params_ref(), result);
TRACE("mk_definition_bug", tout << "after elim_unused_vars:\n" << mk_ismt2_pp(result, m_manager) << "\n";);
TRACE("mk_definition_bug", tout << "before elim_unused_vars:\n" << mk_ismt2_pp(q, m) << "\n";);
result = elim_unused_vars(m, q, params_ref());
TRACE("mk_definition_bug", tout << "after elim_unused_vars:\n" << result << "\n";);
}
}
@ -172,44 +175,81 @@ void defined_names::impl::bound_vars(sort_ref_buffer const & sorts, buffer<symbo
A quantifier is added around \c def_conjunct, if sorts and names are not empty.
In this case, The application \c name is used as a pattern for the new quantifier.
*/
void defined_names::impl::bound_vars(sort_ref_buffer const & sorts, buffer<symbol> const & names, expr * def_conjunct, app * name, expr_ref_buffer & result) {
expr_ref tmp(m_manager);
bound_vars(sorts, names, def_conjunct, name, tmp);
void defined_names::impl::bound_vars(sort_ref_buffer const & sorts, buffer<symbol> const & names, expr * def_conjunct, app * name, expr_ref_buffer & result, symbol const& qid) {
expr_ref tmp(m);
bound_vars(sorts, names, def_conjunct, name, tmp, qid);
result.push_back(tmp);
}
#define MK_OR m_manager.mk_or
#define MK_NOT m_manager.mk_not
#define MK_EQ m_manager.mk_eq
#define MK_OR m.mk_or
#define MK_NOT m.mk_not
#define MK_EQ m.mk_eq
void defined_names::impl::mk_definition(expr * e, app * n, sort_ref_buffer & var_sorts, buffer<symbol> const & var_names, expr_ref & new_def) {
expr_ref_buffer defs(m_manager);
if (m_manager.is_bool(e)) {
void defined_names::impl::mk_definition(expr * e, app * n, sort_ref_buffer & var_sorts, buffer<symbol> & var_names, expr_ref & new_def) {
expr_ref_buffer defs(m);
if (m.is_bool(e)) {
bound_vars(var_sorts, var_names, MK_OR(MK_NOT(n), e), n, defs);
bound_vars(var_sorts, var_names, MK_OR(n, MK_NOT(e)), n, defs);
}
else if (m_manager.is_term_ite(e)) {
else if (m.is_term_ite(e)) {
bound_vars(var_sorts, var_names, MK_OR(MK_NOT(to_app(e)->get_arg(0)), MK_EQ(n, to_app(e)->get_arg(1))), n, defs);
bound_vars(var_sorts, var_names, MK_OR(to_app(e)->get_arg(0), MK_EQ(n, to_app(e)->get_arg(2))), n, defs);
}
else if (is_lambda(e)) {
// n(y) = \x . M[x,y]
// =>
// n(y)[x] = M, forall x y
//
// NB. The pattern is incomplete.
// consider store(a, i, v) == \lambda j . if i = j then v else a[j]
// the instantiation rules for store(a, i, v) are:
// sotre(a, i, v)[j] = if i = j then v else a[j] with patterns {a[j], store(a, i, v)} { store(a, i, v)[j] }
// The first pattern is not included.
// TBD use a model-based scheme for exracting instantiations instead of
// using multi-patterns.
//
quantifier* q = to_quantifier(e);
expr_ref_vector args(m);
expr_ref n2(m), n3(m);
var_shifter vs(m);
vs(n, q->get_num_decls(), n2);
args.push_back(n2);
var_sorts.append(q->get_num_decls(), q->get_decl_sorts());
var_names.append(q->get_num_decls(), q->get_decl_names());
for (unsigned i = 0; i < q->get_num_decls(); ++i) {
args.push_back(m.mk_var(q->get_num_decls() - i - 1, q->get_decl_sort(i)));
}
array_util autil(m);
func_decl * f = 0;
if (autil.is_as_array(n2, f)) {
n3 = m.mk_app(f, args.size()-1, args.c_ptr() + 1);
}
else {
n3 = autil.mk_select(args.size(), args.c_ptr());
}
bound_vars(var_sorts, var_names, MK_EQ(q->get_expr(), n3), to_app(n3), defs, m.lambda_def_qid());
}
else {
bound_vars(var_sorts, var_names, MK_EQ(e, n), n, defs);
}
new_def = defs.size() == 1 ? defs[0] : m_manager.mk_and(defs.size(), defs.c_ptr());
new_def = mk_and(m, defs.size(), defs.c_ptr());
}
void defined_names::pos_impl::mk_definition(expr * e, app * n, sort_ref_buffer & var_sorts, buffer<symbol> const & var_names, expr_ref & new_def) {
void defined_names::pos_impl::mk_definition(expr * e, app * n, sort_ref_buffer & var_sorts, buffer<symbol> & var_names, expr_ref & new_def) {
bound_vars(var_sorts, var_names, MK_OR(MK_NOT(n), e), n, new_def);
}
bool defined_names::impl::mk_name(expr * e, expr_ref & new_def, proof_ref & new_def_pr, app_ref & n, proof_ref & pr) {
TRACE("mk_definition_bug", tout << "making name for:\n" << mk_ismt2_pp(e, m_manager) << "\n";);
TRACE("mk_definition_bug", tout << "making name for:\n" << mk_ismt2_pp(e, m) << "\n";);
app * n_ptr;
if (m_expr2name.find(e, n_ptr)) {
TRACE("mk_definition_bug", tout << "name for expression is already cached..., returning false...\n";);
n = n_ptr;
if (m_manager.proofs_enabled()) {
if (m.proofs_enabled()) {
proof * pr_ptr = nullptr;
m_expr2proof.find(e, pr_ptr);
SASSERT(pr_ptr);
@ -218,24 +258,24 @@ bool defined_names::impl::mk_name(expr * e, expr_ref & new_def, proof_ref & new_
return false;
}
else {
sort_ref_buffer var_sorts(m_manager);
sort_ref_buffer var_sorts(m);
buffer<symbol> var_names;
n = gen_name(e, var_sorts, var_names);
cache_new_name(e, n);
TRACE("mk_definition_bug", tout << "name: " << mk_ismt2_pp(n, m_manager) << "\n";);
TRACE("mk_definition_bug", tout << "name: " << mk_ismt2_pp(n, m) << "\n";);
// variables are in reverse order in quantifiers
std::reverse(var_sorts.c_ptr(), var_sorts.c_ptr() + var_sorts.size());
std::reverse(var_names.c_ptr(), var_names.c_ptr() + var_names.size());
mk_definition(e, n, var_sorts, var_names, new_def);
TRACE("mk_definition_bug", tout << "new_def:\n" << mk_ismt2_pp(new_def, m_manager) << "\n";);
TRACE("mk_definition_bug", tout << "new_def:\n" << mk_ismt2_pp(new_def, m) << "\n";);
if (m_manager.proofs_enabled()) {
new_def_pr = m_manager.mk_def_intro(new_def);
pr = m_manager.mk_apply_def(e, n, new_def_pr);
if (m.proofs_enabled()) {
new_def_pr = m.mk_def_intro(new_def);
pr = m.mk_apply_def(e, n, new_def_pr);
cache_new_name_intro_proof(e, pr);
}
return true;
@ -257,7 +297,7 @@ void defined_names::impl::pop_scope(unsigned num_scopes) {
SASSERT(sz == m_names.size());
while (old_sz != sz) {
--sz;
if (m_manager.proofs_enabled()) {
if (m.proofs_enabled()) {
m_expr2proof.erase(m_exprs.back());
m_apply_proofs.pop_back();
}
@ -296,6 +336,15 @@ bool defined_names::mk_pos_name(expr * e, expr_ref & new_def, proof_ref & new_de
return m_pos_impl->mk_name(e, new_def, new_def_pr, n, pr);
}
expr_ref defined_names::mk_definition(expr * e, app * n) {
ast_manager& m = m_impl->m;
sort_ref_buffer var_sorts(m);
expr_ref new_def(m);
buffer<symbol> var_names;
m_impl->mk_definition(e, n, var_sorts, var_names, new_def);
return new_def;
}
void defined_names::push() {
m_impl->push_scope();
m_pos_impl->push_scope();

View file

@ -77,6 +77,11 @@ public:
*/
bool mk_pos_name(expr * e, expr_ref & new_def, proof_ref & new_def_pr, app_ref & n, proof_ref & pr);
/**
\brief Create a definition for 'n' using 'e'.
*/
expr_ref mk_definition(expr * e, app * n);
void push();
void pop(unsigned num_scopes);
void reset();

View file

@ -22,7 +22,7 @@ Notes:
class name_exprs_core : public name_exprs {
struct cfg : public default_rewriter_cfg {
ast_manager & m_manager;
ast_manager & m;
defined_names & m_defined_names;
expr_predicate & m_pred;
@ -33,7 +33,7 @@ class name_exprs_core : public name_exprs {
proof_ref_vector * m_def_proofs;
cfg(ast_manager & m, defined_names & n, expr_predicate & pred):
m_manager(m),
m(m),
m_defined_names(n),
m_pred(pred),
m_r(m),
@ -43,12 +43,12 @@ class name_exprs_core : public name_exprs {
}
void gen_name_for_expr(expr * n, expr * & t, proof * & t_pr) {
expr_ref new_def(m_manager);
proof_ref new_def_pr(m_manager);
expr_ref new_def(m);
proof_ref new_def_pr(m);
if (m_defined_names.mk_name(n, new_def, new_def_pr, m_r, m_pr)) {
m_def_exprs->push_back(new_def);
if (m_manager.proofs_enabled())
if (m.proofs_enabled())
m_def_proofs->push_back(new_def_pr);
}
@ -57,7 +57,7 @@ class name_exprs_core : public name_exprs {
}
bool get_subst(expr * s, expr * & t, proof * & t_pr) {
TRACE("name_exprs", tout << "get_subst:\n" << mk_ismt2_pp(s, m_manager) << "\n";);
TRACE("name_exprs", tout << "get_subst:\n" << mk_ismt2_pp(s, m) << "\n";);
if (m_pred(s)) {
gen_name_for_expr(s, t, t_pr);
return true;
@ -84,7 +84,7 @@ public:
m_cfg.m_def_exprs = &new_defs;
m_cfg.m_def_proofs = &new_def_proofs;
m_rw(n, r, p);
TRACE("name_exprs", tout << mk_ismt2_pp(n, m_rw.m()) << "\n---->\n" << mk_ismt2_pp(r, m_rw.m()) << "\n";);
TRACE("name_exprs", tout << mk_ismt2_pp(n, m_rw.m()) << "\n---->\n" << r << "\n";);
}
@ -99,11 +99,11 @@ name_exprs * mk_expr_namer(ast_manager & m, defined_names & n, expr_predicate &
class name_quantifier_labels : public name_exprs_core {
class pred : public expr_predicate {
ast_manager & m_manager;
ast_manager & m;
public:
pred(ast_manager & m):m_manager(m) {}
pred(ast_manager & m):m(m) {}
bool operator()(expr * t) override {
return is_quantifier(t) || m_manager.is_label(t);
return is_quantifier(t) || m.is_label(t);
}
};
@ -124,16 +124,16 @@ name_exprs * mk_quantifier_label_namer(ast_manager & m, defined_names & n) {
class name_nested_formulas : public name_exprs_core {
struct pred : public expr_predicate {
ast_manager & m_manager;
ast_manager & m;
expr * m_root;
pred(ast_manager & m):m_manager(m), m_root(nullptr) {}
pred(ast_manager & m):m(m), m_root(0) {}
bool operator()(expr * t) override {
TRACE("name_exprs", tout << "name_nested_formulas::pred:\n" << mk_ismt2_pp(t, m_manager) << "\n";);
TRACE("name_exprs", tout << "name_nested_formulas::pred:\n" << mk_ismt2_pp(t, m) << "\n";);
if (is_app(t))
return to_app(t)->get_family_id() == m_manager.get_basic_family_id() && to_app(t)->get_num_args() > 0 && t != m_root;
return m_manager.is_label(t) || is_quantifier(t);
return to_app(t)->get_family_id() == m.get_basic_family_id() && to_app(t)->get_num_args() > 0 && t != m_root;
return m.is_label(t) || is_quantifier(t);
}
};

View file

@ -17,16 +17,16 @@ Notes:
Major revision on 2011-10-06
--*/
#include "util/warning.h"
#include "util/cooperate.h"
#include "ast/normal_forms/nnf.h"
#include "ast/normal_forms/nnf_params.hpp"
#include "util/warning.h"
#include "ast/used_vars.h"
#include "ast/well_sorted.h"
#include "ast/rewriter/var_subst.h"
#include "ast/normal_forms/name_exprs.h"
#include "ast/act_cache.h"
#include "util/cooperate.h"
#include "ast/rewriter/var_subst.h"
#include "ast/normal_forms/name_exprs.h"
#include "ast/ast_smt2_pp.h"
@ -67,36 +67,42 @@ enum nnf_mode {
class skolemizer {
typedef act_cache cache;
ast_manager & m_manager;
ast_manager & m;
symbol m_sk_hack;
bool m_sk_hack_enabled;
cache m_cache;
cache m_cache_pr;
void process(quantifier * q, expr_ref & r, proof_ref & p) {
if (q->get_kind() == lambda_k) {
TRACE("nnf", tout << expr_ref(q, m) << "\n";);
r = q;
p = nullptr;
return;
}
used_vars uv;
uv(q);
SASSERT(is_well_sorted(m(), q));
SASSERT(is_well_sorted(m, q));
unsigned sz = uv.get_max_found_var_idx_plus_1();
ptr_buffer<sort> sorts;
expr_ref_vector args(m());
expr_ref_vector args(m);
for (unsigned i = 0; i < sz; i++) {
sort * s = uv.get(i);
if (s != nullptr) {
sorts.push_back(s);
args.push_back(m().mk_var(i, s));
args.push_back(m.mk_var(i, s));
}
}
TRACE("skolemizer", tout << "skid: " << q->get_skid() << "\n";);
expr_ref_vector substitution(m());
expr_ref_vector substitution(m);
unsigned num_decls = q->get_num_decls();
for (unsigned i = num_decls; i > 0; ) {
--i;
sort * r = q->get_decl_sort(i);
func_decl * sk_decl = m().mk_fresh_func_decl(q->get_decl_name(i), q->get_skid(), sorts.size(), sorts.c_ptr(), r);
app * sk = m().mk_app(sk_decl, args.size(), args.c_ptr());
func_decl * sk_decl = m.mk_fresh_func_decl(q->get_decl_name(i), q->get_skid(), sorts.size(), sorts.c_ptr(), r);
app * sk = m.mk_app(sk_decl, args.size(), args.c_ptr());
substitution.push_back(sk);
}
//
@ -106,7 +112,7 @@ class skolemizer {
for (unsigned i = 0; i < sz; i++) {
sort * s = uv.get(i);
if (s != nullptr)
substitution.push_back(m().mk_var(i, s));
substitution.push_back(m.mk_var(i, s));
else
substitution.push_back(nullptr);
}
@ -118,9 +124,9 @@ class skolemizer {
//
// (VAR 0) should be in the last position of substitution.
//
var_subst s(m());
SASSERT(is_well_sorted(m(), q->get_expr()));
expr_ref tmp(m());
var_subst s(m);
SASSERT(is_well_sorted(m, q->get_expr()));
expr_ref tmp(m);
expr * body = q->get_expr();
if (m_sk_hack_enabled) {
unsigned num_patterns = q->get_num_patterns();
@ -128,27 +134,27 @@ class skolemizer {
expr * p = q->get_pattern(i);
if (is_sk_hack(p)) {
expr * sk_hack = to_app(p)->get_arg(0);
if (q->is_forall()) // check whether is in negative/positive context.
tmp = m().mk_or(body, m().mk_not(sk_hack)); // negative context
if (q->get_kind() == forall_k) // check whether is in negative/positive context.
tmp = m.mk_or(body, m.mk_not(sk_hack)); // negative context
else
tmp = m().mk_and(body, sk_hack); // positive context
tmp = m.mk_and(body, sk_hack); // positive context
body = tmp;
}
}
}
s(body, substitution.size(), substitution.c_ptr(), r);
r = s(body, substitution.size(), substitution.c_ptr());
p = nullptr;
if (m().proofs_enabled()) {
if (q->is_forall())
p = m().mk_skolemization(m().mk_not(q), m().mk_not(r));
if (m.proofs_enabled()) {
if (q->get_kind() == forall_k)
p = m.mk_skolemization(m.mk_not(q), m.mk_not(r));
else
p = m().mk_skolemization(q, r);
p = m.mk_skolemization(q, r);
}
}
public:
skolemizer(ast_manager & m):
m_manager(m),
m(m),
m_sk_hack("sk_hack"),
m_sk_hack_enabled(false),
m_cache(m),
@ -159,25 +165,23 @@ public:
m_sk_hack_enabled = f;
}
ast_manager & m() const { return m_manager; }
void operator()(quantifier * q, expr_ref & r, proof_ref & p) {
r = m_cache.find(q);
if (r.get() != nullptr) {
p = nullptr;
if (m().proofs_enabled())
if (m.proofs_enabled())
p = static_cast<proof*>(m_cache_pr.find(q));
}
else {
process(q, r, p);
m_cache.insert(q, r);
if (m().proofs_enabled())
if (m.proofs_enabled())
m_cache_pr.insert(q, p);
}
}
bool is_sk_hack(expr * p) const {
SASSERT(m().is_pattern(p));
SASSERT(m.is_pattern(p));
if (to_app(p)->get_num_args() != 1)
return false;
expr * body = to_app(p)->get_arg(0);
@ -186,7 +190,7 @@ public:
func_decl * f = to_app(body)->get_decl();
if (!(f->get_name() == m_sk_hack && f->get_arity() == 1))
return false;
if (!m().is_bool(body)) {
if (!m.is_bool(body)) {
warning_msg("sk_hack constant must return a Boolean");
return false;
}
@ -233,8 +237,8 @@ struct nnf::imp {
#define POS_NQ_CIDX 1 // positive polarity and not nested in a quantifier
#define NEG_Q_CIDX 2 // negative polarity and nested in a quantifier
#define POS_Q_CIDX 3 // positive polarity and nested in a quantifier
ast_manager & m_manager;
ast_manager & m;
vector<frame> m_frame_stack;
expr_ref_vector m_result_stack;
@ -263,7 +267,7 @@ struct nnf::imp {
unsigned long long m_max_memory; // in bytes
imp(ast_manager & m, defined_names & n, params_ref const & p):
m_manager(m),
m(m),
m_result_stack(m),
m_todo_defs(m),
m_todo_proofs(m),
@ -279,9 +283,9 @@ struct nnf::imp {
m_name_quant = mk_quantifier_label_namer(m, n);
}
ast_manager & m() const { return m_manager; }
// ast_manager & m() const { return m; }
bool proofs_enabled() const { return m().proofs_enabled(); }
bool proofs_enabled() const { return m.proofs_enabled(); }
~imp() {
for (unsigned i = 0; i < 4; i++) {
@ -334,7 +338,7 @@ struct nnf::imp {
}
void push_frame(expr * t, bool pol, bool in_q, bool cache_res) {
m_frame_stack.push_back(frame(expr_ref(t, m()), pol, in_q, cache_res, m_result_stack.size()));
m_frame_stack.push_back(frame(expr_ref(t, m), pol, in_q, cache_res, m_result_stack.size()));
}
static unsigned get_cache_idx(bool pol, bool in_q) {
@ -382,8 +386,8 @@ struct nnf::imp {
cooperate("nnf");
if (memory::get_allocation_size() > m_max_memory)
throw nnf_exception(Z3_MAX_MEMORY_MSG);
if (m().canceled())
throw nnf_exception(m().limit().get_cancel_msg());
if (m.canceled())
throw nnf_exception(m.limit().get_cancel_msg());
}
void set_new_child_flag() {
@ -397,16 +401,16 @@ struct nnf::imp {
}
void skip(expr * t, bool pol) {
expr * r = pol ? t : m().mk_not(t);
expr * r = pol ? t : m.mk_not(t);
m_result_stack.push_back(r);
if (proofs_enabled()) {
m_result_pr_stack.push_back(m().mk_oeq_reflexivity(r));
m_result_pr_stack.push_back(m.mk_oeq_reflexivity(r));
SASSERT(m_result_stack.size() == m_result_pr_stack.size());
}
}
bool visit(expr * t, bool pol, bool in_q) {
SASSERT(m().is_bool(t));
SASSERT(m.is_bool(t));
if (m_mode == NNF_SKOLEM || (m_mode == NNF_QUANT && !in_q)) {
if (!has_quantifiers(t) && !has_labels(t)) {
@ -456,12 +460,12 @@ struct nnf::imp {
proof * mk_proof(bool pol, unsigned num_parents, proof * const * parents, app * old_e, app * new_e) {
if (pol) {
if (old_e->get_decl() == new_e->get_decl())
return m().mk_oeq_congruence(old_e, new_e, num_parents, parents);
else
return m().mk_nnf_pos(old_e, new_e, num_parents, parents);
return m.mk_oeq_congruence(old_e, new_e, num_parents, parents);
else
return m.mk_nnf_pos(old_e, new_e, num_parents, parents);
}
else
return m().mk_nnf_neg(old_e, new_e, num_parents, parents);
else
return m.mk_nnf_neg(old_e, new_e, num_parents, parents);
}
bool process_and_or(app * t, frame & fr) {
@ -473,11 +477,11 @@ struct nnf::imp {
return false;
}
app * r;
if (m().is_and(t) == fr.m_pol)
r = m().mk_and(t->get_num_args(), m_result_stack.c_ptr() + fr.m_spos);
if (m.is_and(t) == fr.m_pol)
r = m.mk_and(t->get_num_args(), m_result_stack.c_ptr() + fr.m_spos);
else
r = m().mk_or(t->get_num_args(), m_result_stack.c_ptr() + fr.m_spos);
r = m.mk_or(t->get_num_args(), m_result_stack.c_ptr() + fr.m_spos);
m_result_stack.shrink(fr.m_spos);
m_result_stack.push_back(r);
if (proofs_enabled()) {
@ -500,7 +504,7 @@ struct nnf::imp {
if (proofs_enabled()) {
pr = m_result_pr_stack.back();
if (!fr.m_pol) {
pr = m().mk_nnf_neg(t, r, 1, &pr);
pr = m.mk_nnf_neg(t, r, 1, &pr);
m_result_pr_stack.pop_back();
m_result_pr_stack.push_back(pr);
SASSERT(m_result_stack.size() == m_result_pr_stack.size());
@ -526,10 +530,10 @@ struct nnf::imp {
app * r;
if (fr.m_pol)
r = m().mk_or(2, m_result_stack.c_ptr() + fr.m_spos);
r = m.mk_or(2, m_result_stack.c_ptr() + fr.m_spos);
else
r = m().mk_and(2, m_result_stack.c_ptr() + fr.m_spos);
r = m.mk_and(2, m_result_stack.c_ptr() + fr.m_spos);
m_result_stack.shrink(fr.m_spos);
m_result_stack.push_back(r);
if (proofs_enabled()) {
@ -570,7 +574,7 @@ struct nnf::imp {
expr * _then = rs[2];
expr * _else = rs[3];
app * r = m().mk_and(m().mk_or(_not_cond, _then), m().mk_or(_cond, _else));
app * r = m.mk_and(m.mk_or(_not_cond, _then), m.mk_or(_cond, _else));
m_result_stack.shrink(fr.m_spos);
m_result_stack.push_back(r);
if (proofs_enabled()) {
@ -582,7 +586,7 @@ struct nnf::imp {
return true;
}
bool is_eq(app * t) const { return m().is_eq(t); }
bool is_eq(app * t) const { return m.is_eq(t); }
bool process_iff_xor(app * t, frame & fr) {
SASSERT(t->get_num_args() == 2);
@ -614,10 +618,10 @@ struct nnf::imp {
expr * not_rhs = rs[3];
app * r;
if (is_eq(t) == fr.m_pol)
r = m().mk_and(m().mk_or(not_lhs, rhs), m().mk_or(lhs, not_rhs));
if (is_eq(t) == fr.m_pol)
r = m.mk_and(m.mk_or(not_lhs, rhs), m.mk_or(lhs, not_rhs));
else
r = m().mk_and(m().mk_or(lhs, rhs), m().mk_or(not_lhs, not_rhs));
r = m.mk_and(m.mk_or(lhs, rhs), m.mk_or(not_lhs, not_rhs));
m_result_stack.shrink(fr.m_spos);
m_result_stack.push_back(r);
if (proofs_enabled()) {
@ -630,7 +634,7 @@ struct nnf::imp {
}
bool process_eq(app * t, frame & fr) {
if (m().is_iff(t))
if (m.is_bool(t->get_arg(0)))
return process_iff_xor(t, fr);
else
return process_default(t, fr);
@ -639,21 +643,20 @@ struct nnf::imp {
bool process_default(app * t, frame & fr) {
SASSERT(fr.m_i == 0);
if (m_mode == NNF_FULL || t->has_quantifiers() || t->has_labels()) {
expr_ref n2(m());
proof_ref pr2(m());
expr_ref n2(m);
proof_ref pr2(m);
if (m_mode == NNF_FULL || (m_mode != NNF_SKOLEM && fr.m_in_q))
m_name_nested_formulas->operator()(t, m_todo_defs, m_todo_proofs, n2, pr2);
else
m_name_quant->operator()(t, m_todo_defs, m_todo_proofs, n2, pr2);
if (!fr.m_pol)
n2 = m().mk_not(n2);
n2 = m.mk_not(n2);
m_result_stack.push_back(n2);
if (proofs_enabled()) {
if (!fr.m_pol) {
proof * prs[1] = { pr2 };
pr2 = m().mk_oeq_congruence(m().mk_not(t), static_cast<app*>(n2.get()), 1, prs);
pr2 = m.mk_oeq_congruence(m.mk_not(t), static_cast<app*>(n2.get()), 1, prs);
}
m_result_pr_stack.push_back(pr2);
SASSERT(m_result_stack.size() == m_result_pr_stack.size());
@ -681,24 +684,24 @@ struct nnf::imp {
buffer<symbol> names;
bool pos;
m().is_label(t, pos, names);
expr_ref r(m());
proof_ref pr(m());
m.is_label(t, pos, names);
expr_ref r(m);
proof_ref pr(m);
if (fr.m_pol == pos) {
expr * lbl_lit = m().mk_label_lit(names.size(), names.c_ptr());
r = m().mk_and(arg, lbl_lit);
expr * lbl_lit = m.mk_label_lit(names.size(), names.c_ptr());
r = m.mk_and(arg, lbl_lit);
if (proofs_enabled()) {
expr_ref aux(m_manager);
aux = m().mk_label(true, names.size(), names.c_ptr(), arg);
pr = m().mk_transitivity(mk_proof(fr.m_pol, 1, &arg_pr, t, to_app(aux)),
m().mk_iff_oeq(m().mk_rewrite(aux, r)));
expr_ref aux(m);
aux = m.mk_label(true, names.size(), names.c_ptr(), arg);
pr = m.mk_transitivity(mk_proof(fr.m_pol, 1, &arg_pr, t, to_app(aux)),
m.mk_iff_oeq(m.mk_rewrite(aux, r)));
}
}
else {
r = arg;
if (proofs_enabled()) {
proof * p1 = m().mk_iff_oeq(m().mk_rewrite(t, t->get_arg(0)));
pr = m().mk_transitivity(p1, arg_pr);
proof * p1 = m.mk_iff_oeq(m.mk_rewrite(t, t->get_arg(0)));
pr = m.mk_transitivity(p1, arg_pr);
}
}
@ -713,9 +716,9 @@ struct nnf::imp {
}
bool process_app(app * t, frame & fr) {
TRACE("nnf", tout << mk_ismt2_pp(t, m()) << "\n";);
SASSERT(m().is_bool(t));
if (t->get_family_id() == m().get_basic_family_id()) {
TRACE("nnf", tout << mk_ismt2_pp(t, m) << "\n";);
SASSERT(m.is_bool(t));
if (t->get_family_id() == m.get_basic_family_id()) {
switch (static_cast<basic_op_kind>(t->get_decl_kind())) {
case OP_AND: case OP_OR:
return process_and_or(t, fr);
@ -734,7 +737,7 @@ struct nnf::imp {
}
}
if (m().is_label(t)) {
if (m.is_label(t)) {
return process_label(t, fr);
}
@ -747,28 +750,51 @@ struct nnf::imp {
}
bool process_quantifier(quantifier * q, frame & fr) {
expr_ref r(m());
proof_ref pr(m());
TRACE("nnf", tout << expr_ref(q, m) << "\n";);
expr_ref r(m);
proof_ref pr(m);
if (fr.m_i == 0) {
fr.m_i = 1;
if (q->is_forall() == fr.m_pol || !m_skolemize) {
if (is_lambda(q)) {
if (!visit(q->get_expr(), fr.m_pol, true))
return false;
}
else if (is_forall(q) == fr.m_pol || !m_skolemize) {
if (!visit(q->get_expr(), fr.m_pol, true))
return false;
}
else {
m_skolemizer(q, r, pr);
if (!visit(r, !q->is_forall(), fr.m_in_q))
if (!visit(r, !is_forall(q), fr.m_in_q))
return false;
}
}
if (q->is_forall() == fr.m_pol || !m_skolemize) {
if (is_lambda(q)) {
expr * new_expr = m_result_stack.back();
quantifier * new_q = m.update_quantifier(q, new_expr);
proof * new_q_pr = nullptr;
if (proofs_enabled()) {
// proof * new_expr_pr = m_result_pr_stack.back();
new_q_pr = m.mk_rewrite(q, new_q); // TBD use new_expr_pr
}
m_result_stack.pop_back();
m_result_stack.push_back(new_q);
if (proofs_enabled()) {
m_result_pr_stack.pop_back();
m_result_pr_stack.push_back(new_q_pr);
SASSERT(m_result_stack.size() == m_result_pr_stack.size());
}
return true;
}
else if (is_forall(q) == fr.m_pol || !m_skolemize) {
expr * new_expr = m_result_stack.back();
proof * new_expr_pr = proofs_enabled() ? m_result_pr_stack.back() : nullptr;
ptr_buffer<expr> new_patterns;
if (q->is_forall() == fr.m_pol) {
if (is_forall(q) == fr.m_pol) {
// collect non sk_hack patterns
unsigned num_patterns = q->get_num_patterns();
for (unsigned i = 0; i < num_patterns; i++) {
@ -785,14 +811,19 @@ struct nnf::imp {
quantifier * new_q = nullptr;
proof * new_q_pr = nullptr;
if (fr.m_pol) {
new_q = m().update_quantifier(q, new_patterns.size(), new_patterns.c_ptr(), new_expr);
if (proofs_enabled())
new_q_pr = m().mk_nnf_pos(q, new_q, 1, &new_expr_pr);
new_q = m.update_quantifier(q, new_patterns.size(), new_patterns.c_ptr(), new_expr);
if (proofs_enabled()) {
new_expr_pr = m.mk_bind_proof(q, new_expr_pr);
new_q_pr = m.mk_nnf_pos(q, new_q, 1, &new_expr_pr);
}
}
else {
new_q = m().update_quantifier(q, !q->is_forall(), new_patterns.size(), new_patterns.c_ptr(), new_expr);
if (proofs_enabled())
new_q_pr = m().mk_nnf_neg(q, new_q, 1, &new_expr_pr);
quantifier_kind k = is_forall(q)? exists_k : forall_k;
new_q = m.update_quantifier(q, k, new_patterns.size(), new_patterns.c_ptr(), new_expr);
if (proofs_enabled()) {
new_expr_pr = m.mk_bind_proof(q, new_expr_pr);
new_q_pr = m.mk_nnf_neg(q, new_q, 1, &new_expr_pr);
}
}
m_result_stack.pop_back();
@ -809,7 +840,7 @@ struct nnf::imp {
// However, the proof must be updated
if (proofs_enabled()) {
m_skolemizer(q, r, pr); // retrieve the proof
pr = m().mk_transitivity(pr, m_result_pr_stack.back());
pr = m.mk_transitivity(pr, m_result_pr_stack.back());
m_result_pr_stack.pop_back();
m_result_pr_stack.push_back(pr);
SASSERT(m_result_stack.size() == m_result_pr_stack.size());
@ -827,14 +858,14 @@ struct nnf::imp {
result_pr = m_result_pr_stack.back();
m_result_pr_stack.pop_back();
if (result_pr.get() == nullptr)
result_pr = m().mk_reflexivity(t);
result_pr = m.mk_reflexivity(t);
SASSERT(m_result_pr_stack.empty());
}
}
void process(expr * t, expr_ref & result, proof_ref & result_pr) {
TRACE("nnf", tout << "processing:\n" << mk_ismt2_pp(t, m()) << "\n";);
SASSERT(m().is_bool(t));
TRACE("nnf", tout << "processing:\n" << mk_ismt2_pp(t, m) << "\n";);
SASSERT(m.is_bool(t));
if (visit(t, true /* positive polarity */, false /* not nested in quantifier */)) {
recover_result(t, result, result_pr);
@ -883,13 +914,13 @@ struct nnf::imp {
unsigned old_sz2 = new_def_proofs.size();
for (unsigned i = 0; i < m_todo_defs.size(); i++) {
expr_ref dr(m());
proof_ref dpr(m());
expr_ref dr(m);
proof_ref dpr(m);
process(m_todo_defs.get(i), dr, dpr);
new_defs.push_back(dr);
if (proofs_enabled()) {
proof * new_pr = m().mk_modus_ponens(m_todo_proofs.get(i), dpr);
new_def_proofs.push_back(new_pr);
proof * new_pr = m.mk_modus_ponens(m_todo_proofs.get(i), dpr);
new_def_proofs.push_back(new_pr);
}
}
std::reverse(new_defs.c_ptr() + old_sz1, new_defs.c_ptr() + new_defs.size());
@ -909,7 +940,7 @@ nnf::~nnf() {
void nnf::operator()(expr * n, expr_ref_vector & new_defs, proof_ref_vector & new_def_proofs, expr_ref & r, proof_ref & p) {
m_imp->operator()(n, new_defs, new_def_proofs, r, p);
TRACE("nnf_result", tout << mk_ismt2_pp(n, m_imp->m()) << "\nNNF result:\n" << mk_ismt2_pp(r, m_imp->m()) << "\n";);
TRACE("nnf_result", tout << expr_ref(n, r.get_manager()) << "\nNNF result:\n" << new_defs << "\n" << r << "\n";);
}
void nnf::updt_params(params_ref const & p) {

View file

@ -49,7 +49,8 @@ struct pull_quant::imp {
if (is_quantifier(child)) {
quantifier * q = to_quantifier(child);
expr * body = q->get_expr();
result = m_manager.update_quantifier(q, !q->is_forall(), m_manager.mk_not(body));
quantifier_kind k = q->get_kind() == forall_k ? exists_k : forall_k;
result = m_manager.update_quantifier(q, k, m_manager.mk_not(body));
return true;
}
else {
@ -149,7 +150,7 @@ struct pull_quant::imp {
// 3) MBQI
std::reverse(var_sorts.begin(), var_sorts.end());
std::reverse(var_names.begin(), var_names.end());
result = m_manager.mk_quantifier(forall_children,
result = m_manager.mk_quantifier(forall_children ? forall_k : exists_k,
var_sorts.size(),
var_sorts.c_ptr(),
var_names.c_ptr(),
@ -220,9 +221,7 @@ struct pull_quant::imp {
expr_ref_buffer new_args(m_manager);
expr_ref new_arg(m_manager);
ptr_buffer<proof> proofs;
unsigned num = to_app(n)->get_num_args();
for (unsigned i = 0; i < num; i++) {
expr * arg = to_app(n)->get_arg(i);
for (expr * arg : *to_app(n)) {
pull_quant1(arg , new_arg);
new_args.push_back(new_arg);
if (new_arg != arg)
@ -277,10 +276,13 @@ struct pull_quant::imp {
expr_ref & result,
proof_ref & result_pr) {
if (old_q->is_exists()) {
if (is_exists(old_q)) {
UNREACHABLE();
return false;
}
if (is_lambda(old_q)) {
return false;
}
if (!is_forall(new_body))
return false;

View file

@ -53,7 +53,7 @@ expr_pattern_match::match_quantifier(quantifier* qf, app_ref_vector& patterns, u
m_regs[0] = qf->get_expr();
for (unsigned i = 0; i < m_precompiled.size(); ++i) {
quantifier* qf2 = m_precompiled[i].get();
if (qf2->is_forall() != qf->is_forall()) {
if (qf2->get_kind() != qf->get_kind() || is_lambda(qf)) {
continue;
}
if (qf2->get_num_decls() != qf->get_num_decls()) {

View file

@ -582,7 +582,7 @@ bool pattern_inference_cfg::reduce_quantifier(
proof_ref & result_pr) {
TRACE("pattern_inference", tout << "processing:\n" << mk_pp(q, m) << "\n";);
if (!q->is_forall()) {
if (!is_forall(q)) {
return false;
}
@ -673,6 +673,7 @@ bool pattern_inference_cfg::reduce_quantifier(
new_q = m.update_quantifier_weight(new_q, weight);
if (m.proofs_enabled()) {
proof* new_body_pr = m.mk_reflexivity(new_body);
new_body_pr = m.mk_bind_proof(new_q, new_body_pr);
result_pr = m.mk_quant_intro(q, new_q, new_body_pr);
}
@ -690,7 +691,7 @@ bool pattern_inference_cfg::reduce_quantifier(
}
new_q = m.update_quantifier(result2, new_patterns.size(), (expr**) new_patterns.c_ptr(), result2->get_expr());
if (m.proofs_enabled()) {
result_pr = m.mk_transitivity(new_pr, m.mk_quant_intro(result2, new_q, m.mk_reflexivity(new_q->get_expr())));
result_pr = m.mk_transitivity(new_pr, m.mk_quant_intro(result2, new_q, m.mk_bind_proof(new_q, m.mk_reflexivity(new_q->get_expr()))));
}
TRACE("pattern_inference", tout << "pulled quantifier:\n" << mk_pp(new_q, m) << "\n";);
}

View file

@ -92,7 +92,7 @@ func_decl * pb_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, p
}
void pb_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol const & logic) {
if (logic == symbol::null || logic == "QF_FD" || logic == "ALL") {
if (logic == symbol::null || logic == "QF_FD" || logic == "ALL" || logic == "HORN") {
op_names.push_back(builtin_name(m_at_most_sym.bare_str(), OP_AT_MOST_K));
op_names.push_back(builtin_name(m_at_least_sym.bare_str(), OP_AT_LEAST_K));
op_names.push_back(builtin_name(m_pble_sym.bare_str(), OP_PB_LE));

View file

@ -140,8 +140,8 @@ bool proof_checker::check1_spc(proof* p, expr_ref_vector& side_conditions) {
proof_ref_vector proofs(m);
if (match_proof(p, proofs)) {
for (unsigned i = 0; i < proofs.size(); ++i) {
add_premise(proofs[i].get());
for (proof* pr : proofs) {
add_premise(pr);
}
}
switch(k) {
@ -188,22 +188,22 @@ bool proof_checker::check1_spc(proof* p, expr_ref_vector& side_conditions) {
bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
decl_kind k = p->get_decl_kind();
expr_ref fml0(m), fml1(m), fml2(m), fml(m);
expr_ref t1(m), t2(m);
expr_ref s1(m), s2(m);
expr_ref u1(m), u2(m);
expr_ref fact(m), body1(m), body2(m);
expr_ref l1(m), l2(m), r1(m), r2(m);
func_decl_ref d1(m), d2(m), d3(m);
proof_ref p0(m), p1(m), p2(m);
expr* fml0 = nullptr, *fml1 = nullptr, *fml2 = nullptr, *fml = nullptr;
expr* t1 = nullptr, *t2 = nullptr;
expr* s1 = nullptr, *s2 = nullptr;
expr* u1 = nullptr, *u2 = nullptr;
expr* fact = nullptr, *body1 = nullptr, *body2 = nullptr;
expr* l1 = nullptr, *l2 = nullptr, *r1 = nullptr, *r2 = nullptr;
func_decl* d1 = nullptr, *d2 = nullptr, *d3 = nullptr;
proof* p0 = nullptr, *p1 = nullptr, *p2 = nullptr;
proof_ref_vector proofs(m);
func_decl_ref f1(m), f2(m);
expr_ref_vector terms1(m), terms2(m), terms(m);
func_decl* f1 = nullptr, *f2 = nullptr;
ptr_vector<expr> terms1, terms2, terms;
sort_ref_vector decls1(m), decls2(m);
if (match_proof(p, proofs)) {
for (unsigned i = 0; i < proofs.size(); ++i) {
add_premise(proofs.get(i));
for (proof* pr : proofs) {
add_premise(pr);
}
}
@ -219,11 +219,11 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
case PR_MODUS_PONENS: {
if (match_fact(p, fact) &&
match_proof(p, p0, p1) &&
match_fact(p0.get(), fml0) &&
match_fact(p1.get(), fml1) &&
(match_implies(fml1.get(), t1, t2) || match_iff(fml1.get(), t1, t2)) &&
(fml0.get() == t1.get()) &&
(fact.get() == t2.get())) {
match_fact(p0, fml0) &&
match_fact(p1, fml1) &&
(match_implies(fml1, t1, t2) || match_iff(fml1, t1, t2)) &&
(fml0 == t1) &&
(fact == t2)) {
return true;
}
UNREACHABLE();
@ -233,7 +233,7 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
if (match_fact(p, fact) &&
match_proof(p) &&
(match_equiv(fact, t1, t2) || match_oeq(fact, t1, t2)) &&
(t1.get() == t2.get())) {
(t1 == t2)) {
return true;
}
UNREACHABLE();
@ -242,12 +242,12 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
case PR_SYMMETRY: {
if (match_fact(p, fact) &&
match_proof(p, p1) &&
match_fact(p1.get(), fml) &&
match_binary(fact.get(), d1, l1, r1) &&
match_binary(fml.get(), d2, l2, r2) &&
SAME_OP(d1.get(), d2.get()) &&
l1.get() == r2.get() &&
r1.get() == l2.get()) {
match_fact(p1, fml) &&
match_binary(fact, d1, l1, r1) &&
match_binary(fml, d2, l2, r2) &&
SAME_OP(d1, d2) &&
l1 == r2 &&
r1 == l2) {
// TBD d1, d2 is a symmetric predicate
return true;
}
@ -257,16 +257,16 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
case PR_TRANSITIVITY: {
if (match_fact(p, fact) &&
match_proof(p, p1, p2) &&
match_fact(p1.get(), fml1) &&
match_fact(p2.get(), fml2) &&
match_binary(fact.get(), d1, t1, t2) &&
match_binary(fml1.get(), d2, s1, s2) &&
match_binary(fml2.get(), d3, u1, u2) &&
d1.get() == d2.get() &&
d2.get() == d3.get() &&
t1.get() == s1.get() &&
s2.get() == u1.get() &&
u2.get() == t2.get()) {
match_fact(p1, fml1) &&
match_fact(p2, fml2) &&
match_binary(fact, d1, t1, t2) &&
match_binary(fml1, d2, s1, s2) &&
match_binary(fml2, d3, u1, u2) &&
d1 == d2 &&
d2 == d3 &&
t1 == s1 &&
s2 == u1 &&
u2 == t2) {
// TBD d1 is some transitive predicate.
return true;
}
@ -275,13 +275,13 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
}
case PR_TRANSITIVITY_STAR: {
if (match_fact(p, fact) &&
match_binary(fact.get(), d1, t1, t2)) {
match_binary(fact, d1, t1, t2)) {
u_map<bool> vertices;
// TBD check that d1 is transitive, symmetric.
for (unsigned i = 0; i < proofs.size(); ++i) {
if (match_fact(proofs[i].get(), fml) &&
match_binary(fml.get(), d2, s1, s2) &&
d1.get() == d2.get()) {
for (proof* pr : proofs) {
if (match_fact(pr, fml) &&
match_binary(fml, d2, s1, s2) &&
d1 == d2) {
unsigned id1 = s1->get_id();
unsigned id2 = s2->get_id();
#define INSERT(_id) if (vertices.contains(_id)) vertices.remove(_id); else vertices.insert(_id, true);
@ -304,24 +304,24 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
case PR_MONOTONICITY: {
TRACE("proof_checker", tout << mk_bounded_pp(p, m, 3) << "\n";);
if (match_fact(p, fact) &&
match_binary(fact.get(), d1, t1, t2) &&
match_app(t1.get(), f1, terms1) &&
match_app(t2.get(), f2, terms2) &&
f1.get() == f2.get() &&
match_binary(fact, d1, t1, t2) &&
match_app(t1, f1, terms1) &&
match_app(t2, f2, terms2) &&
f1 == f2 &&
terms1.size() == terms2.size()) {
// TBD: d1 is monotone.
for (unsigned i = 0; i < terms1.size(); ++i) {
expr* term1 = terms1[i].get();
expr* term2 = terms2[i].get();
expr* term1 = terms1[i];
expr* term2 = terms2[i];
if (term1 != term2) {
bool found = false;
for(unsigned j = 0; j < proofs.size() && !found; ++j) {
found =
match_fact(proofs[j].get(), fml) &&
match_binary(fml.get(), d2, s1, s2) &&
SAME_OP(d1.get(), d2.get()) &&
s1.get() == term1 &&
s2.get() == term2;
for (proof* pr : proofs) {
found |=
match_fact(pr, fml) &&
match_binary(fml, d2, s1, s2) &&
SAME_OP(d1, d2) &&
s1 == term1 &&
s2 == term2;
}
if (!found) {
UNREACHABLE();
@ -337,18 +337,24 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
case PR_QUANT_INTRO: {
if (match_proof(p, p1) &&
match_fact(p, fact) &&
match_fact(p1.get(), fml) &&
(match_iff(fact.get(), t1, t2) || match_oeq(fact.get(), t1, t2)) &&
(match_iff(fml.get(), s1, s2) || match_oeq(fml.get(), s1, s2)) &&
m.is_oeq(fact.get()) == m.is_oeq(fml.get()) &&
is_quantifier(t1.get()) &&
is_quantifier(t2.get()) &&
to_quantifier(t1.get())->get_expr() == s1.get() &&
to_quantifier(t2.get())->get_expr() == s2.get() &&
to_quantifier(t1.get())->get_num_decls() == to_quantifier(t2.get())->get_num_decls() &&
to_quantifier(t1.get())->is_forall() == to_quantifier(t2.get())->is_forall()) {
quantifier* q1 = to_quantifier(t1.get());
quantifier* q2 = to_quantifier(t2.get());
match_fact(p1, fml) &&
(is_lambda(fact) || is_lambda(fml)))
return true;
if (match_proof(p, p1) &&
match_fact(p, fact) &&
match_fact(p1, fml) &&
(match_iff(fact, t1, t2) || match_oeq(fact, t1, t2)) &&
(match_iff(fml, s1, s2) || match_oeq(fml, s1, s2)) &&
m.is_oeq(fact) == m.is_oeq(fml) &&
is_quantifier(t1) &&
is_quantifier(t2) &&
to_quantifier(t1)->get_expr() == s1 &&
to_quantifier(t2)->get_expr() == s2 &&
to_quantifier(t1)->get_num_decls() == to_quantifier(t2)->get_num_decls() &&
to_quantifier(t1)->get_kind() == to_quantifier(t2)->get_kind()) {
quantifier* q1 = to_quantifier(t1);
quantifier* q2 = to_quantifier(t2);
for (unsigned i = 0; i < q1->get_num_decls(); ++i) {
if (q1->get_decl_sort(i) != q2->get_decl_sort(i)) {
// term is not well-typed.
@ -361,40 +367,43 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
UNREACHABLE();
return false;
}
case PR_BIND:
// it is a lambda expression returning a proof object.
if (!is_lambda(to_app(p)->get_arg(0)))
return false;
// check that body is a proof object.
return true;
case PR_DISTRIBUTIVITY: {
if (match_fact(p, fact) &&
match_proof(p) &&
match_equiv(fact.get(), t1, t2)) {
side_conditions.push_back(fact.get());
match_equiv(fact, t1, t2)) {
side_conditions.push_back(fact);
return true;
}
UNREACHABLE();
return false;
}
case PR_AND_ELIM: {
expr_ref_vector terms(m);
if (match_proof(p, p1) &&
match_fact(p, fact) &&
match_fact(p1.get(), fml) &&
match_and(fml.get(), terms)) {
for (unsigned i = 0; i < terms.size(); ++i) {
if (terms[i].get() == fact.get()) {
return true;
}
}
match_fact(p1, fml) &&
match_and(fml, terms)) {
for (expr* t : terms)
if (t == fact) return true;
}
UNREACHABLE();
return false;
}
case PR_NOT_OR_ELIM: {
expr_ref_vector terms(m);
if (match_proof(p, p1) &&
match_fact(p, fact) &&
match_fact(p1.get(), fml) &&
match_not(fml.get(), fml1) &&
match_or(fml1.get(), terms)) {
for (unsigned i = 0; i < terms.size(); ++i) {
if (match_negated(terms[i].get(), fact.get())) {
match_fact(p1, fml) &&
match_not(fml, fml1) &&
match_or(fml1, terms)) {
for (expr* t : terms) {
if (match_negated(t, fact)) {
return true;
}
}
@ -405,8 +414,8 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
case PR_REWRITE: {
if (match_fact(p, fact) &&
match_proof(p) &&
match_equiv(fact.get(), t1, t2)) {
side_conditions.push_back(fact.get());
match_equiv(fact, t1, t2)) {
side_conditions.push_back(fact);
return true;
}
IF_VERBOSE(0, verbose_stream() << "Expected proof of equality:\n" << mk_bounded_pp(p, m););
@ -414,12 +423,12 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
}
case PR_REWRITE_STAR: {
if (match_fact(p, fact) &&
match_equiv(fact.get(), t1, t2)) {
match_equiv(fact, t1, t2)) {
expr_ref_vector rewrite_eq(m);
rewrite_eq.push_back(fact.get());
for (unsigned i = 0; i < proofs.size(); ++i) {
if (match_fact(proofs[i].get(), fml)) {
rewrite_eq.push_back(m.mk_not(fml.get()));
rewrite_eq.push_back(fact);
for (proof* pr : proofs) {
if (match_fact(pr, fml)) {
rewrite_eq.push_back(m.mk_not(fml));
}
}
expr_ref rewrite_cond(m);
@ -433,8 +442,8 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
case PR_PULL_QUANT: {
if (match_proof(p) &&
match_fact(p, fact) &&
match_iff(fact.get(), t1, t2) &&
is_quantifier(t2.get())) {
match_iff(fact, t1, t2) &&
is_quantifier(t2)) {
// TBD: check the enchilada.
return true;
}
@ -444,16 +453,16 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
case PR_PUSH_QUANT: {
if (match_proof(p) &&
match_fact(p, fact) &&
match_iff(fact.get(), t1, t2) &&
is_quantifier(t1.get()) &&
match_and(to_quantifier(t1.get())->get_expr(), terms1) &&
match_and(t2.get(), terms2) &&
match_iff(fact, t1, t2) &&
is_quantifier(t1) &&
match_and(to_quantifier(t1)->get_expr(), terms1) &&
match_and(t2, terms2) &&
terms1.size() == terms2.size()) {
quantifier * q1 = to_quantifier(t1.get());
quantifier * q1 = to_quantifier(t1);
for (unsigned i = 0; i < terms1.size(); ++i) {
if (is_quantifier(terms2[i].get()) &&
to_quantifier(terms2[i].get())->get_expr() == terms1[i].get() &&
to_quantifier(terms2[i].get())->get_num_decls() == q1->get_num_decls()) {
if (is_quantifier(terms2[i]) &&
to_quantifier(terms2[i])->get_expr() == terms1[i] &&
to_quantifier(terms2[i])->get_num_decls() == q1->get_num_decls()) {
// ok.
}
else {
@ -467,9 +476,9 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
case PR_ELIM_UNUSED_VARS: {
if (match_proof(p) &&
match_fact(p, fact) &&
match_iff(fact.get(), t1, t2)) {
match_iff(fact, t1, t2)) {
// TBD:
// match_quantifier(t1.get(), is_forall1, decls1, body1)
// match_quantifier(t1, is_forall1, decls1, body1)
// filter out decls1 that occur in body1.
// if list is empty, then t2 could be just body1.
// otherwise t2 is also a quantifier.
@ -482,7 +491,7 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
bool is_forall = false;
if (match_proof(p) &&
match_fact(p, fact) &&
match_iff(fact.get(), t1, t2) &&
match_iff(fact, t1, t2) &&
match_quantifier(t1, is_forall, decls1, body1) &&
is_forall) {
// TBD: check that terms are set of equalities.
@ -503,18 +512,18 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
case PR_LEMMA: {
if (match_proof(p, p1) &&
match_fact(p, fact) &&
match_fact(p1.get(), fml) &&
m.is_false(fml.get())) {
match_fact(p1, fml) &&
m.is_false(fml)) {
expr_ref_vector hypotheses(m);
expr_ref_vector ors(m);
get_hypotheses(p1.get(), hypotheses);
get_hypotheses(p1, hypotheses);
if (hypotheses.size() == 1 && match_negated(hypotheses.get(0), fact)) {
// Suppose fact is (or a b c) and hypothesis is (not (or a b c))
// That is, (or a b c) should be viewed as a 'quoted expression' and a unary clause,
// instead of a clause with three literals.
return true;
}
get_ors(fact.get(), ors);
get_ors(fact, ors);
for (unsigned i = 0; i < hypotheses.size(); ++i) {
bool found = false;
unsigned j;
@ -524,14 +533,9 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
if (!found) {
TRACE("pr_lemma_bug",
tout << "i: " << i << "\n";
tout << "ORs:\n";
for (unsigned i = 0; i < ors.size(); i++) {
tout << mk_pp(ors.get(i), m) << "\n";
}
tout << "HYPOTHESIS:\n";
for (unsigned i = 0; i < hypotheses.size(); i++) {
tout << mk_pp(hypotheses.get(i), m) << "\n";
});
tout << "ORs:\n" << ors << "\n";
tout << "HYPOTHESIS:\n" << hypotheses << "\n";
);
UNREACHABLE();
return false;
}
@ -549,14 +553,14 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
proofs.size() == 2 &&
match_fact(proofs[0].get(), fml1) &&
match_fact(proofs[1].get(), fml2) &&
m.is_complement(fml1.get(), fml2.get()) &&
m.is_false(fact.get())) {
m.is_complement(fml1, fml2) &&
m.is_false(fact)) {
return true;
}
if (match_fact(p, fact) &&
proofs.size() > 1 &&
match_fact(proofs.get(0), fml) &&
match_or(fml.get(), terms1)) {
match_or(fml, terms1)) {
for (unsigned i = 1; i < proofs.size(); ++i) {
if (!match_fact(proofs.get(i), fml2)) {
return false;
@ -575,7 +579,7 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
TRACE("pr_unit_bug",
tout << "Parents:\n";
for (unsigned i = 0; i < proofs.size(); i++) {
expr_ref p(m);
expr* p = nullptr;
match_fact(proofs.get(i), p);
tout << mk_pp(p, m) << "\n";
}
@ -592,16 +596,15 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
}
switch(terms1.size()) {
case 0:
return m.is_false(fact.get());
return m.is_false(fact);
case 1:
return fact.get() == terms1[0].get();
return fact == terms1[0];
default: {
if (match_or(fact.get(), terms2)) {
for (unsigned i = 0; i < terms1.size(); ++i) {
if (match_or(fact, terms2)) {
for (expr* term1 : terms1) {
bool found = false;
expr* term1 = terms1[i].get();
for (unsigned j = 0; !found && j < terms2.size(); ++j) {
found = term1 == terms2[j].get();
for (expr* term2 : terms2) {
found = term1 == term2;
}
if (!found) {
IF_VERBOSE(0, verbose_stream() << "Premise not found:" << mk_pp(term1, m) << "\n";);
@ -611,8 +614,8 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
return true;
}
IF_VERBOSE(0, verbose_stream() << "Conclusion is not a disjunction:\n";
verbose_stream() << mk_pp(fml.get(), m) << "\n";
verbose_stream() << mk_pp(fact.get(), m) << "\n";);
verbose_stream() << mk_pp(fml, m) << "\n";
verbose_stream() << mk_pp(fact, m) << "\n";);
return false;
}
@ -626,10 +629,10 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
// iff_true(?rule(?p1, ?fml), (iff ?fml true))
if (match_proof(p, p1) &&
match_fact(p, fact) &&
match_fact(p1.get(), fml1) &&
match_iff(fact.get(), l1, r1) &&
fml1.get() == l1.get() &&
r1.get() == m.mk_true()) {
match_fact(p1, fml1) &&
match_iff(fact, l1, r1) &&
fml1 == l1 &&
r1 == m.mk_true()) {
return true;
}
UNREACHABLE();
@ -639,11 +642,11 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
// iff_false(?rule(?p1, (not ?fml)), (iff ?fml false))
if (match_proof(p, p1) &&
match_fact(p, fact) &&
match_fact(p1.get(), fml1) &&
match_iff(fact.get(), l1, r1) &&
match_not(fml1.get(), t1) &&
t1.get() == l1.get() &&
r1.get() == m.mk_false()) {
match_fact(p1, fml1) &&
match_iff(fact, l1, r1) &&
match_not(fml1, t1) &&
t1 == l1 &&
r1 == m.mk_false()) {
return true;
}
UNREACHABLE();
@ -653,12 +656,12 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
// commutativity(= (?c ?t1 ?t2) (?c ?t2 ?t1))
if (match_fact(p, fact) &&
match_proof(p) &&
match_equiv(fact.get(), t1, t2) &&
match_binary(t1.get(), d1, s1, s2) &&
match_binary(t2.get(), d2, u1, u2) &&
s1.get() == u2.get() &&
s2.get() == u1.get() &&
d1.get() == d2.get() &&
match_equiv(fact, t1, t2) &&
match_binary(t1, d1, s1, s2) &&
match_binary(t2, d2, u1, u2) &&
s1 == u2 &&
s2 == u1 &&
d1 == d2 &&
d1->is_commutative()) {
return true;
}
@ -669,7 +672,7 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
// axiom(?fml)
if (match_fact(p, fact) &&
match_proof(p) &&
m.is_bool(fact.get())) {
m.is_bool(fact)) {
return true;
}
UNREACHABLE();
@ -684,7 +687,7 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
//
if (match_fact(p, fact) &&
match_proof(p) &&
m.is_bool(fact.get())) {
m.is_bool(fact)) {
return true;
}
UNREACHABLE();
@ -692,7 +695,7 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
}
case PR_APPLY_DEF: {
if (match_fact(p, fact) &&
match_oeq(fact.get(), t1, t2)) {
match_oeq(fact, t1, t2)) {
// TBD: must definitions be in proofs?
return true;
}
@ -703,11 +706,11 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
// axiom(?rule(?p1,(iff ?t1 ?t2)), (~ ?t1 ?t2))
if (match_fact(p, fact) &&
match_proof(p, p1) &&
match_oeq(fact.get(), t1, t2) &&
match_fact(p1.get(), fml) &&
match_iff(fml.get(), s1, s2) &&
s1.get() == t1.get() &&
s2.get() == t2.get()) {
match_oeq(fact, t1, t2) &&
match_fact(p1, fml) &&
match_iff(fml, s1, s2) &&
s1 == t1 &&
s2 == t2) {
return true;
}
UNREACHABLE();
@ -725,18 +728,19 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
// (exists ?x (p ?x y)) -> (p (sk y) y)
// (not (forall ?x (p ?x y))) -> (not (p (sk y) y))
if (match_fact(p, fact) &&
match_oeq(fact.get(), t1, t2)) {
match_oeq(fact, t1, t2)) {
quantifier* q = nullptr;
expr* e = t1.get();
expr* e = t1;
bool is_forall = false;
if (match_not(t1.get(), s1)) {
e = s1.get();
if (match_not(t1, s1)) {
e = s1;
is_forall = true;
}
if (is_quantifier(e)) {
q = to_quantifier(e);
SASSERT(!is_lambda(e));
q = to_quantifier(e);
// TBD check that quantifier is properly instantiated
return is_forall == q->is_forall();
return is_forall == ::is_forall(q);
}
}
UNREACHABLE();
@ -745,11 +749,11 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
case PR_MODUS_PONENS_OEQ: {
if (match_fact(p, fact) &&
match_proof(p, p0, p1) &&
match_fact(p0.get(), fml0) &&
match_fact(p1.get(), fml1) &&
match_oeq(fml1.get(), t1, t2) &&
fml0.get() == t1.get() &&
fact.get() == t2.get()) {
match_fact(p0, fml0) &&
match_fact(p1, fml1) &&
match_oeq(fml1, t1, t2) &&
fml0 == t1 &&
fact == t2) {
return true;
}
UNREACHABLE();
@ -784,7 +788,7 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
// SASSERT(to_quantifier(premise)->get_num_decls() == sub.size());
premise = to_quantifier(premise)->get_expr();
}
vs(premise, sub.size(), sub.c_ptr(), premise);
premise = vs(premise, sub.size(), sub.c_ptr());
}
fmls.push_back(premise.get());
TRACE("proof_checker",
@ -896,7 +900,7 @@ void proof_checker::set_false(expr_ref& e, unsigned position, expr_ref& lit) {
}
}
bool proof_checker::match_fact(proof const* p, expr_ref& fact) const {
bool proof_checker::match_fact(proof const* p, expr*& fact) const {
if (m.is_proof(p) &&
m.has_fact(p)) {
fact = m.get_fact(p);
@ -918,7 +922,7 @@ bool proof_checker::match_proof(proof const* p) const {
m.get_num_parents(p) == 0;
}
bool proof_checker::match_proof(proof const* p, proof_ref& p0) const {
bool proof_checker::match_proof(proof const* p, proof*& p0) const {
if (m.is_proof(p) &&
m.get_num_parents(p) == 1) {
p0 = m.get_parent(p, 0);
@ -927,7 +931,7 @@ bool proof_checker::match_proof(proof const* p, proof_ref& p0) const {
return false;
}
bool proof_checker::match_proof(proof const* p, proof_ref& p0, proof_ref& p1) const {
bool proof_checker::match_proof(proof const* p, proof*& p0, proof*& p1) const {
if (m.is_proof(p) &&
m.get_num_parents(p) == 2) {
p0 = m.get_parent(p, 0);
@ -948,7 +952,7 @@ bool proof_checker::match_proof(proof const* p, proof_ref_vector& parents) const
}
bool proof_checker::match_binary(expr const* e, func_decl_ref& d, expr_ref& t1, expr_ref& t2) const {
bool proof_checker::match_binary(expr const* e, func_decl*& d, expr*& t1, expr*& t2) const {
if (e->get_kind() == AST_APP &&
to_app(e)->get_num_args() == 2) {
d = to_app(e)->get_decl();
@ -960,21 +964,21 @@ bool proof_checker::match_binary(expr const* e, func_decl_ref& d, expr_ref& t1,
}
bool proof_checker::match_app(expr const* e, func_decl_ref& d, expr_ref_vector& terms) const {
bool proof_checker::match_app(expr const* e, func_decl*& d, ptr_vector<expr>& terms) const {
if (e->get_kind() == AST_APP) {
d = to_app(e)->get_decl();
for (unsigned i = 0; i < to_app(e)->get_num_args(); ++i) {
terms.push_back(to_app(e)->get_arg(i));
for (expr* arg : *to_app(e)) {
terms.push_back(arg);
}
return true;
}
return false;
}
bool proof_checker::match_quantifier(expr const* e, bool& is_univ, sort_ref_vector& sorts, expr_ref& body) const {
bool proof_checker::match_quantifier(expr const* e, bool& is_univ, sort_ref_vector& sorts, expr*& body) const {
if (is_quantifier(e)) {
quantifier const* q = to_quantifier(e);
is_univ = q->is_forall();
is_univ = is_forall(q);
body = q->get_expr();
for (unsigned i = 0; i < q->get_num_decls(); ++i) {
sorts.push_back(q->get_decl_sort(i));
@ -984,7 +988,7 @@ bool proof_checker::match_quantifier(expr const* e, bool& is_univ, sort_ref_vect
return false;
}
bool proof_checker::match_op(expr const* e, decl_kind k, expr_ref& t1, expr_ref& t2) const {
bool proof_checker::match_op(expr const* e, decl_kind k, expr*& t1, expr*& t2) const {
if (e->get_kind() == AST_APP &&
to_app(e)->get_family_id() == m.get_basic_family_id() &&
to_app(e)->get_decl_kind() == k &&
@ -996,20 +1000,19 @@ bool proof_checker::match_op(expr const* e, decl_kind k, expr_ref& t1, expr_ref&
return false;
}
bool proof_checker::match_op(expr const* e, decl_kind k, expr_ref_vector& terms) const {
bool proof_checker::match_op(expr const* e, decl_kind k, ptr_vector<expr>& terms) const {
if (e->get_kind() == AST_APP &&
to_app(e)->get_family_id() == m.get_basic_family_id() &&
to_app(e)->get_decl_kind() == k) {
for (unsigned i = 0; i < to_app(e)->get_num_args(); ++i) {
terms.push_back(to_app(e)->get_arg(i));
}
for (expr* arg : *to_app(e))
terms.push_back(arg);
return true;
}
return false;
}
bool proof_checker::match_op(expr const* e, decl_kind k, expr_ref& t) const {
bool proof_checker::match_op(expr const* e, decl_kind k, expr*& t) const {
if (e->get_kind() == AST_APP &&
to_app(e)->get_family_id() == m.get_basic_family_id() &&
to_app(e)->get_decl_kind() == k &&
@ -1020,43 +1023,43 @@ bool proof_checker::match_op(expr const* e, decl_kind k, expr_ref& t) const {
return false;
}
bool proof_checker::match_not(expr const* e, expr_ref& t) const {
bool proof_checker::match_not(expr const* e, expr*& t) const {
return match_op(e, OP_NOT, t);
}
bool proof_checker::match_or(expr const* e, expr_ref_vector& terms) const {
bool proof_checker::match_or(expr const* e, ptr_vector<expr>& terms) const {
return match_op(e, OP_OR, terms);
}
bool proof_checker::match_and(expr const* e, expr_ref_vector& terms) const {
bool proof_checker::match_and(expr const* e, ptr_vector<expr>& terms) const {
return match_op(e, OP_AND, terms);
}
bool proof_checker::match_iff(expr const* e, expr_ref& t1, expr_ref& t2) const {
bool proof_checker::match_iff(expr const* e, expr*& t1, expr*& t2) const {
return match_op(e, OP_EQ, t1, t2) && m.is_bool(t1);
}
bool proof_checker::match_equiv(expr const* e, expr_ref& t1, expr_ref& t2) const {
bool proof_checker::match_equiv(expr const* e, expr*& t1, expr*& t2) const {
return match_oeq(e, t1, t2) || match_eq(e, t1, t2);
}
bool proof_checker::match_implies(expr const* e, expr_ref& t1, expr_ref& t2) const {
bool proof_checker::match_implies(expr const* e, expr*& t1, expr*& t2) const {
return match_op(e, OP_IMPLIES, t1, t2);
}
bool proof_checker::match_eq(expr const* e, expr_ref& t1, expr_ref& t2) const {
bool proof_checker::match_eq(expr const* e, expr*& t1, expr*& t2) const {
return match_op(e, OP_EQ, t1, t2);
}
bool proof_checker::match_oeq(expr const* e, expr_ref& t1, expr_ref& t2) const {
bool proof_checker::match_oeq(expr const* e, expr*& t1, expr*& t2) const {
return match_op(e, OP_OEQ, t1, t2);
}
bool proof_checker::match_negated(expr const* a, expr* b) const {
expr_ref t(m);
expr* t = nullptr;
return
(match_not(a, t) && t.get() == b) ||
(match_not(b, t) && t.get() == a);
(match_not(a, t) && t == b) ||
(match_not(b, t) && t == a);
}
void proof_checker::get_ors(expr* e, expr_ref_vector& ors) {
@ -1073,8 +1076,7 @@ void proof_checker::get_ors(expr* e, expr_ref_vector& ors) {
void proof_checker::get_hypotheses(proof* p, expr_ref_vector& ante) {
ptr_vector<proof> stack;
expr* h = nullptr;
expr_ref hyp(m);
expr* h = nullptr, *hyp = nullptr;
stack.push_back(p);
while (!stack.empty()) {
@ -1085,9 +1087,9 @@ void proof_checker::get_hypotheses(proof* p, expr_ref_vector& ante) {
continue;
}
if (is_hypothesis(p) && match_fact(p, hyp)) {
hyp = mk_atom(hyp.get());
m_pinned.push_back(hyp.get());
m_hypotheses.insert(p, hyp.get());
hyp = mk_atom(hyp);
m_pinned.push_back(hyp);
m_hypotheses.insert(p, hyp);
stack.pop_back();
continue;
}
@ -1128,7 +1130,7 @@ void proof_checker::get_hypotheses(proof* p, expr_ref_vector& ante) {
ptr_buffer<expr> todo;
expr_mark mark;
todo.push_back(h);
expr_ref a(m), b(m);
expr* a = nullptr, *b = nullptr;
while (!todo.empty()) {
h = todo.back();
@ -1139,11 +1141,11 @@ void proof_checker::get_hypotheses(proof* p, expr_ref_vector& ante) {
}
mark.mark(h, true);
if (match_cons(h, a, b)) {
todo.push_back(a.get());
todo.push_back(b.get());
todo.push_back(a);
todo.push_back(b);
}
else if (match_atom(h, a)) {
ante.push_back(a.get());
ante.push_back(a);
}
else {
SASSERT(match_nil(h));
@ -1167,7 +1169,7 @@ bool proof_checker::match_nil(expr const* e) const {
to_app(e)->get_decl_kind() == OP_NIL;
}
bool proof_checker::match_cons(expr const* e, expr_ref& a, expr_ref& b) const {
bool proof_checker::match_cons(expr const* e, expr*& a, expr*& b) const {
if (is_app(e) &&
to_app(e)->get_family_id() == m_hyp_fid &&
to_app(e)->get_decl_kind() == OP_CONS) {
@ -1179,7 +1181,7 @@ bool proof_checker::match_cons(expr const* e, expr_ref& a, expr_ref& b) const {
}
bool proof_checker::match_atom(expr const* e, expr_ref& a) const {
bool proof_checker::match_atom(expr const* e, expr*& a) const {
if (is_app(e) &&
to_app(e)->get_family_id() == m_hyp_fid &&
to_app(e)->get_decl_kind() == OP_ATOM) {
@ -1358,7 +1360,7 @@ bool proof_checker::check_arith_proof(proof* p) {
dump_proof(p);
return true;
}
expr_ref fact(m);
expr* fact = nullptr;
proof_ref_vector proofs(m);
if (!match_fact(p, fact)) {

View file

@ -77,33 +77,33 @@ private:
bool check1_spc(proof* p, expr_ref_vector& side_conditions);
bool check_arith_proof(proof* p);
bool check_arith_literal(bool is_pos, app* lit, rational const& coeff, expr_ref& sum, bool& is_strict);
bool match_fact(proof const* p, expr_ref& fact) const;
bool match_fact(proof const* p, expr*& fact) const;
void add_premise(proof* p);
bool match_proof(proof const* p) const;
bool match_proof(proof const* p, proof_ref& p0) const;
bool match_proof(proof const* p, proof_ref& p0, proof_ref& p1) const;
bool match_proof(proof const* p, proof*& p0) const;
bool match_proof(proof const* p, proof*& p0, proof*& p1) const;
bool match_proof(proof const* p, proof_ref_vector& parents) const;
bool match_binary(expr const* e, func_decl_ref& d, expr_ref& t1, expr_ref& t2) const;
bool match_op(expr const* e, decl_kind k, expr_ref& t1, expr_ref& t2) const;
bool match_op(expr const* e, decl_kind k, expr_ref& t) const;
bool match_op(expr const* e, decl_kind k, expr_ref_vector& terms) const;
bool match_iff(expr const* e, expr_ref& t1, expr_ref& t2) const;
bool match_implies(expr const* e, expr_ref& t1, expr_ref& t2) const;
bool match_eq(expr const* e, expr_ref& t1, expr_ref& t2) const;
bool match_oeq(expr const* e, expr_ref& t1, expr_ref& t2) const;
bool match_not(expr const* e, expr_ref& t) const;
bool match_or(expr const* e, expr_ref_vector& terms) const;
bool match_and(expr const* e, expr_ref_vector& terms) const;
bool match_app(expr const* e, func_decl_ref& d, expr_ref_vector& terms) const;
bool match_quantifier(expr const*, bool& is_univ, sort_ref_vector&, expr_ref& body) const;
bool match_binary(expr const* e, func_decl*& d, expr*& t1, expr*& t2) const;
bool match_op(expr const* e, decl_kind k, expr*& t1, expr*& t2) const;
bool match_op(expr const* e, decl_kind k, expr*& t) const;
bool match_op(expr const* e, decl_kind k, ptr_vector<expr>& terms) const;
bool match_iff(expr const* e, expr*& t1, expr*& t2) const;
bool match_implies(expr const* e, expr*& t1, expr*& t2) const;
bool match_eq(expr const* e, expr*& t1, expr*& t2) const;
bool match_oeq(expr const* e, expr*& t1, expr*& t2) const;
bool match_not(expr const* e, expr*& t) const;
bool match_or(expr const* e, ptr_vector<expr>& terms) const;
bool match_and(expr const* e, ptr_vector<expr>& terms) const;
bool match_app(expr const* e, func_decl*& d, ptr_vector<expr>& terms) const;
bool match_quantifier(expr const*, bool& is_univ, sort_ref_vector&, expr*& body) const;
bool match_negated(expr const* a, expr* b) const;
bool match_equiv(expr const* a, expr_ref& t1, expr_ref& t2) const;
bool match_equiv(expr const* a, expr*& t1, expr*& t2) const;
void get_ors(expr* e, expr_ref_vector& ors);
void get_hypotheses(proof* p, expr_ref_vector& ante);
bool match_nil(expr const* e) const;
bool match_cons(expr const* e, expr_ref& a, expr_ref& b) const;
bool match_atom(expr const* e, expr_ref& a) const;
bool match_cons(expr const* e, expr*& a, expr*& b) const;
bool match_atom(expr const* e, expr*& a) const;
expr* mk_nil();
expr* mk_cons(expr* a, expr* b);
expr* mk_atom(expr* e);

View file

@ -975,9 +975,7 @@ private:
void compose(expr_ref_vector& sub, expr_ref_vector const& s0) {
for (unsigned i = 0; i < sub.size(); ++i) {
expr_ref e(m);
var_subst(m, false)(sub[i].get(), s0.size(), s0.c_ptr(), e);
sub[i] = e;
sub[i] = var_subst(m, false)(sub[i].get(), s0.size(), s0.c_ptr());
}
}
@ -995,7 +993,7 @@ private:
tout << sub.size() << "\n";);
return;
}
var_subst(m, false)(q->get_expr(), sub.size(), sub.c_ptr(), fml);
fml = var_subst(m, false)(q->get_expr(), sub.size(), sub.c_ptr());
}
};

View file

@ -164,10 +164,12 @@ public:
// skip (asserted m_aux)
else if (m.is_asserted(arg, a) && a == m_aux.get()) {
dirty = true;
args.push_back(m.mk_true_proof());
}
// skip (hypothesis m_aux)
else if (m.is_hypothesis(arg, a) && a == m_aux.get()) {
dirty = true;
args.push_back(m.mk_true_proof());
} else if (is_app(arg) && cache.find(to_app(arg), r)) {
dirty |= (arg != r);
args.push_back(r);
@ -188,14 +190,18 @@ public:
app_ref newp(m);
if (!dirty) { newp = p; }
else if (m.is_unit_resolution(p)) {
if (args.size() == 2)
// unit resolution with m_aux that got collapsed to nothing
{ newp = to_app(args.get(0)); }
ptr_buffer<proof> parents;
for (unsigned i = 0, sz = args.size() - 1; i < sz; ++i) {
app *arg = to_app(args.get(i));
if (!m.is_true(m.get_fact(arg)))
parents.push_back(arg);
}
// unit resolution that collapsed to nothing
if (parents.size() == 1) {
newp = parents.get(0);
}
else {
ptr_vector<proof> parents;
for (unsigned i = 0, sz = args.size() - 1; i < sz; ++i)
{ parents.push_back(to_app(args.get(i))); }
SASSERT(parents.size() == args.size() - 1);
// rebuild unit resolution
newp = m.mk_unit_resolution(parents.size(), parents.c_ptr());
// XXX the old and new facts should be
// equivalent. The test here is much
@ -203,9 +209,11 @@ public:
SASSERT(m.get_fact(newp) == args.back());
pinned.push_back(newp);
}
} else if (matches_fact(args, a)) {
}
else if (matches_fact(args, a)) {
newp = to_app(a);
} else {
}
else {
expr_ref papp(m);
mk_app(p->get_decl(), args, papp);
newp = to_app(papp.get());

View file

@ -801,106 +801,104 @@ br_status arith_rewriter::mk_idiv_core(expr * arg1, expr * arg2, expr_ref & resu
return BR_DONE;
}
if (m_util.is_numeral(arg2, v2, is_int) && v2.is_one()) {
result = arg1;
return BR_DONE;
}
if (m_util.is_numeral(arg2, v2, is_int) && v2.is_zero()) {
return BR_FAILED;
}
if (arg1 == arg2) {
expr_ref zero(m_util.mk_int(0), m());
result = m().mk_ite(m().mk_eq(arg1, zero), m_util.mk_idiv(zero, zero), m_util.mk_int(1));
return BR_REWRITE3;
}
if (divides(arg1, arg2, result)) {
return BR_REWRITE_FULL;
}
result = arg1;
return BR_DONE;
}
if (m_util.is_numeral(arg2, v2, is_int) && v2.is_zero()) {
return BR_FAILED;
}
if (arg1 == arg2) {
expr_ref zero(m_util.mk_int(0), m());
result = m().mk_ite(m().mk_eq(arg1, zero), m_util.mk_idiv(zero, zero), m_util.mk_int(1));
return BR_REWRITE3;
}
if (divides(arg1, arg2, result)) {
return BR_REWRITE_FULL;
}
return BR_FAILED;
}
//
// implement div ab ac = floor( ab / ac) = floor (b / c) = div b c
//
// implement div ab ac = floor( ab / ac) = floor (b / c) = div b c
//
bool arith_rewriter::divides(expr* num, expr* den, expr_ref& result) {
expr_fast_mark1 mark;
rational num_r(1), den_r(1);
expr* num_e = nullptr, *den_e = nullptr;
ptr_buffer<expr> args1, args2;
flat_mul(num, args1);
flat_mul(den, args2);
for (expr * arg : args1) {
mark.mark(arg);
if (m_util.is_numeral(arg, num_r)) num_e = arg;
}
for (expr* arg : args2) {
if (mark.is_marked(arg)) {
result = remove_divisor(arg, num, den);
return true;
}
if (m_util.is_numeral(arg, den_r)) den_e = arg;
}
rational g = gcd(num_r, den_r);
if (!g.is_one()) {
SASSERT(g.is_pos());
// replace num_e, den_e by their gcd reduction.
for (unsigned i = 0; i < args1.size(); ++i) {
if (args1[i] == num_e) {
args1[i] = m_util.mk_numeral(num_r / g, true);
break;
}
}
for (unsigned i = 0; i < args2.size(); ++i) {
if (args2[i] == den_e) {
args2[i] = m_util.mk_numeral(den_r / g, true);
break;
}
}
num = m_util.mk_mul(args1.size(), args1.c_ptr());
den = m_util.mk_mul(args2.size(), args2.c_ptr());
result = m_util.mk_idiv(num, den);
return true;
}
return false;
}
expr_ref arith_rewriter::remove_divisor(expr* arg, expr* num, expr* den) {
ptr_buffer<expr> args1, args2;
flat_mul(num, args1);
flat_mul(den, args2);
remove_divisor(arg, args1);
remove_divisor(arg, args2);
expr_ref zero(m_util.mk_int(0), m());
num = args1.empty() ? m_util.mk_int(1) : m_util.mk_mul(args1.size(), args1.c_ptr());
den = args2.empty() ? m_util.mk_int(1) : m_util.mk_mul(args2.size(), args2.c_ptr());
return expr_ref(m().mk_ite(m().mk_eq(zero, arg), m_util.mk_idiv(zero, zero), m_util.mk_idiv(num, den)), m());
}
void arith_rewriter::flat_mul(expr* e, ptr_buffer<expr>& args) {
args.push_back(e);
for (unsigned i = 0; i < args.size(); ++i) {
e = args[i];
if (m_util.is_mul(e)) {
args.append(to_app(e)->get_num_args(), to_app(e)->get_args());
args[i] = args.back();
args.shrink(args.size()-1);
--i;
}
}
}
void arith_rewriter::remove_divisor(expr* d, ptr_buffer<expr>& args) {
for (unsigned i = 0; i < args.size(); ++i) {
if (args[i] == d) {
args[i] = args.back();
args.shrink(args.size()-1);
return;
}
}
UNREACHABLE();
}
bool arith_rewriter::divides(expr* num, expr* den, expr_ref& result) {
expr_fast_mark1 mark;
rational num_r(1), den_r(1);
expr* num_e = nullptr, *den_e = nullptr;
ptr_buffer<expr> args1, args2;
flat_mul(num, args1);
flat_mul(den, args2);
for (expr * arg : args1) {
mark.mark(arg);
if (m_util.is_numeral(arg, num_r)) num_e = arg;
}
for (expr* arg : args2) {
if (mark.is_marked(arg)) {
result = remove_divisor(arg, num, den);
return true;
}
if (m_util.is_numeral(arg, den_r)) den_e = arg;
}
rational g = gcd(num_r, den_r);
if (!g.is_one()) {
SASSERT(g.is_pos());
// replace num_e, den_e by their gcd reduction.
for (unsigned i = 0; i < args1.size(); ++i) {
if (args1[i] == num_e) {
args1[i] = m_util.mk_numeral(num_r / g, true);
break;
}
}
for (unsigned i = 0; i < args2.size(); ++i) {
if (args2[i] == den_e) {
args2[i] = m_util.mk_numeral(den_r / g, true);
break;
}
}
num = m_util.mk_mul(args1.size(), args1.c_ptr());
den = m_util.mk_mul(args2.size(), args2.c_ptr());
result = m_util.mk_idiv(num, den);
return true;
}
return false;
}
expr_ref arith_rewriter::remove_divisor(expr* arg, expr* num, expr* den) {
ptr_buffer<expr> args1, args2;
flat_mul(num, args1);
flat_mul(den, args2);
remove_divisor(arg, args1);
remove_divisor(arg, args2);
expr_ref zero(m_util.mk_int(0), m());
num = args1.empty() ? m_util.mk_int(1) : m_util.mk_mul(args1.size(), args1.c_ptr());
den = args2.empty() ? m_util.mk_int(1) : m_util.mk_mul(args2.size(), args2.c_ptr());
return expr_ref(m().mk_ite(m().mk_eq(zero, arg), m_util.mk_idiv(zero, zero), m_util.mk_idiv(num, den)), m());
}
void arith_rewriter::flat_mul(expr* e, ptr_buffer<expr>& args) {
args.push_back(e);
for (unsigned i = 0; i < args.size(); ++i) {
e = args[i];
if (m_util.is_mul(e)) {
args.append(to_app(e)->get_num_args(), to_app(e)->get_args());
args[i] = args.back();
args.shrink(args.size()-1);
--i;
}
}
}
void arith_rewriter::remove_divisor(expr* d, ptr_buffer<expr>& args) {
for (unsigned i = 0; i < args.size(); ++i) {
if (args[i] == d) {
args[i] = args.back();
args.shrink(args.size()-1);
return;
}
}
UNREACHABLE();
}
br_status arith_rewriter::mk_mod_core(expr * arg1, expr * arg2, expr_ref & result) {
set_curr_sort(m().get_sort(arg1));
numeral v1, v2;
@ -1159,49 +1157,44 @@ br_status arith_rewriter::mk_to_int_core(expr * arg, expr_ref & result) {
result = m_util.mk_numeral(floor(a), true);
return BR_DONE;
}
else if (m_util.is_to_real(arg, x)) {
if (m_util.is_to_real(arg, x)) {
result = x;
return BR_DONE;
}
else {
if (m_util.is_add(arg) || m_util.is_mul(arg) || m_util.is_power(arg)) {
// Try to apply simplifications such as:
// (to_int (+ 1.0 (to_real x))) --> (+ 1 x)
// if all arguments of arg are
// - integer numerals, OR
// - to_real applications
// then, to_int can be eliminated
unsigned num_args = to_app(arg)->get_num_args();
unsigned i = 0;
for (; i < num_args; i++) {
expr * c = to_app(arg)->get_arg(i);
if (m_util.is_numeral(c, a) && a.is_int())
continue;
if (m_util.is_to_real(c))
continue;
break; // failed
if (m_util.is_add(arg) || m_util.is_mul(arg) || m_util.is_power(arg)) {
// Try to apply simplifications such as:
// (to_int (+ 1.0 (to_real x)) y) --> (+ 1 x (to_int y))
expr_ref_buffer int_args(m()), real_args(m());
for (expr* c : *to_app(arg)) {
if (m_util.is_numeral(c, a) && a.is_int()) {
int_args.push_back(m_util.mk_numeral(a, true));
}
if (i == num_args) {
// simplification can be applied
expr_ref_buffer new_args(m());
for (i = 0; i < num_args; i++) {
expr * c = to_app(arg)->get_arg(i);
if (m_util.is_numeral(c, a) && a.is_int()) {
new_args.push_back(m_util.mk_numeral(a, true));
}
else {
VERIFY (m_util.is_to_real(c, x));
new_args.push_back(x);
}
}
SASSERT(num_args == new_args.size());
result = m().mk_app(get_fid(), to_app(arg)->get_decl()->get_decl_kind(), new_args.size(), new_args.c_ptr());
return BR_REWRITE1;
else if (m_util.is_to_real(c, x)) {
int_args.push_back(x);
}
else {
real_args.push_back(c);
}
}
return BR_FAILED;
if (real_args.empty()) {
result = m().mk_app(get_fid(), to_app(arg)->get_decl()->get_decl_kind(), int_args.size(), int_args.c_ptr());
return BR_REWRITE1;
}
if (!int_args.empty() && (m_util.is_add(arg) || m_util.is_mul(arg))) {
decl_kind k = to_app(arg)->get_decl()->get_decl_kind();
expr_ref t1(m().mk_app(get_fid(), k, int_args.size(), int_args.c_ptr()), m());
expr_ref t2(m().mk_app(get_fid(), k, real_args.size(), real_args.c_ptr()), m());
int_args.reset();
int_args.push_back(t1);
int_args.push_back(m_util.mk_to_int(t2));
result = m().mk_app(get_fid(), k, int_args.size(), int_args.c_ptr());
return BR_REWRITE3;
}
}
return BR_FAILED;
}
br_status arith_rewriter::mk_to_real_core(expr * arg, expr_ref & result) {

View file

@ -96,10 +96,9 @@ class arith_rewriter : public poly_rewriter<arith_rewriter_core> {
expr * mk_sin_value(rational const & k);
app * mk_sqrt(rational const & k);
bool divides(expr* d, expr* n, expr_ref& result);
expr_ref remove_divisor(expr* arg, expr* num, expr* den);
void flat_mul(expr* e, ptr_buffer<expr>& args);
void remove_divisor(expr* d, ptr_buffer<expr>& args);
expr_ref remove_divisor(expr* arg, expr* num, expr* den);
void flat_mul(expr* e, ptr_buffer<expr>& args);
void remove_divisor(expr* d, ptr_buffer<expr>& args);
public:
arith_rewriter(ast_manager & m, params_ref const & p = params_ref()):
poly_rewriter<arith_rewriter_core>(m, p) {

View file

@ -20,6 +20,7 @@ Notes:
#include "ast/rewriter/array_rewriter_params.hpp"
#include "ast/ast_lt.h"
#include "ast/ast_pp.h"
#include "ast/rewriter/var_subst.h"
void array_rewriter::updt_params(params_ref const & _p) {
array_rewriter_params p(_p);
@ -196,6 +197,17 @@ br_status array_rewriter::mk_select_core(unsigned num_args, expr * const * args,
return BR_DONE;
}
if (is_lambda(args[0])) {
// anywhere lambda reduction as opposed to whnf
// select(lambda(X) M, N) -> M[N/X]
quantifier* q = to_quantifier(args[0]);
SASSERT(q->get_num_decls() == num_args - 1);
var_subst subst(m());
result = subst(q->get_expr(), num_args - 1, args + 1);
return BR_REWRITE_FULL;
}
if (m_util.is_as_array(args[0])) {
// select(as-array[f], I) --> f(I)
func_decl * f = m_util.get_as_array_func_decl(to_app(args[0]));

View file

@ -89,6 +89,7 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
expr_ref_vector m_out;
obj_map<func_decl, expr*> m_const2bits;
expr_ref_vector m_bindings;
unsigned_vector m_shifts;
func_decl_ref_vector m_keys;
expr_ref_vector m_values;
unsigned_vector m_keyval_lim;
@ -579,19 +580,36 @@ MK_PARAMETRIC_UNARY_REDUCE(reduce_sign_extend, mk_sign_extend);
}
SASSERT(new_bindings.size() == q->get_num_decls());
i = q->get_num_decls();
unsigned shift = j;
if (!m_shifts.empty()) shift += m_shifts.back();
while (i > 0) {
i--;
m_bindings.push_back(new_bindings[i]);
m_shifts.push_back(shift);
}
}
return true;
}
bool reduce_var(var * t, expr_ref & result, proof_ref & result_pr) {
if (m_blast_quant) {
if (t->get_idx() >= m_bindings.size())
if (m_blast_quant) {
if (m_bindings.empty())
return false;
result = m_bindings.get(m_bindings.size() - t->get_idx() - 1);
unsigned shift = m_shifts.back();
if (t->get_idx() >= m_bindings.size()) {
if (shift == 0)
return false;
result = m_manager.mk_var(t->get_idx() + shift, t->get_sort());
}
else {
unsigned offset = m_bindings.size() - t->get_idx() - 1;
result = m_bindings.get(offset);
shift = shift - m_shifts[offset];
if (shift > 0) {
var_shifter vs(m_manager);
vs(result, shift, result);
}
}
result_pr = nullptr;
return true;
}
@ -636,11 +654,12 @@ MK_PARAMETRIC_UNARY_REDUCE(reduce_sign_extend, mk_sign_extend);
new_decl_names.push_back(n);
}
}
result = m().mk_quantifier(old_q->is_forall(), new_decl_sorts.size(), new_decl_sorts.c_ptr(), new_decl_names.c_ptr(),
result = m().mk_quantifier(old_q->get_kind(), new_decl_sorts.size(), new_decl_sorts.c_ptr(), new_decl_names.c_ptr(),
new_body, old_q->get_weight(), old_q->get_qid(), old_q->get_skid(),
old_q->get_num_patterns(), new_patterns, old_q->get_num_no_patterns(), new_no_patterns);
result_pr = nullptr;
m_bindings.shrink(old_sz);
m_shifts.shrink(old_sz);
return true;
}
};

View file

@ -588,58 +588,39 @@ br_status bool_rewriter::try_ite_value(app * ite, app * val, expr_ref & result)
VERIFY(m().is_ite(ite, cond, t, e));
SASSERT(m().is_value(val));
if (m().is_value(t) && m().is_value(e)) {
if (t != val && e != val) {
TRACE("try_ite_value", tout << mk_ismt2_pp(t, m()) << " " << mk_ismt2_pp(e, m()) << " " << mk_ismt2_pp(val, m()) << "\n";
tout << t << " " << e << " " << val << "\n";);
result = m().mk_false();
}
else if (t == val && e == val) {
if (m().are_distinct(val, e)) {
result = m().mk_and(m().mk_eq(t, val), cond);
return BR_REWRITE2;
}
if (m().are_distinct(val, t)) {
result = m().mk_and(m().mk_eq(e, val), m().mk_not(cond));
return BR_REWRITE2;
}
if (m().are_equal(val, t)) {
if (m().are_equal(val, e)) {
result = m().mk_true();
}
else if (t == val) {
result = cond;
return BR_DONE;
}
else {
SASSERT(e == val);
mk_not(cond, result);
result = m().mk_or(m().mk_eq(e, val), cond);
}
return BR_DONE;
return BR_REWRITE2;
}
if (m_ite_extra_rules) {
if (m().is_value(t)) {
if (val == t) {
result = m().mk_or(cond, m().mk_eq(val, e));
}
else {
mk_not(cond, result);
result = m().mk_and(result, m().mk_eq(val, e));
}
return BR_REWRITE2;
}
if (m().is_value(e)) {
if (val == e) {
mk_not(cond, result);
result = m().mk_or(result, m().mk_eq(val, t));
}
else {
result = m().mk_and(cond, m().mk_eq(val, t));
}
return BR_REWRITE2;
}
if (m().are_equal(val, e)) {
result = m().mk_or(m().mk_eq(t, val), m().mk_not(cond));
return BR_REWRITE2;
}
{
expr* cond2, *t2, *e2;
if (m().is_ite(t, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
try_ite_value(to_app(t), val, result);
result = m().mk_ite(cond, result, m().mk_eq(e, val));
return BR_REWRITE2;
}
if (m().is_ite(e, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
try_ite_value(to_app(e), val, result);
result = m().mk_ite(cond, m().mk_eq(t, val), result);
return BR_REWRITE2;
}
expr* cond2 = nullptr, *t2 = nullptr, *e2 = nullptr;
if (m().is_ite(t, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
try_ite_value(to_app(t), val, result);
result = m().mk_ite(cond, result, m().mk_eq(e, val));
return BR_REWRITE2;
}
if (m().is_ite(e, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
try_ite_value(to_app(e), val, result);
result = m().mk_ite(cond, m().mk_eq(t, val), result);
return BR_REWRITE2;
}
return BR_FAILED;

View file

@ -87,20 +87,16 @@ bool bv_elim_cfg::reduce_quantifier(quantifier * q,
expr* const* sub = subst_map.c_ptr();
unsigned sub_size = subst_map.size();
subst(old_body, sub_size, sub, new_body);
new_body = subst(old_body, sub_size, sub);
for (unsigned j = 0; j < q->get_num_patterns(); j++) {
expr_ref pat(m);
subst(new_patterns[j], sub_size, sub, pat);
pats.push_back(pat);
pats.push_back(subst(new_patterns[j], sub_size, sub));
}
for (unsigned j = 0; j < q->get_num_no_patterns(); j++) {
expr_ref nopat(m);
subst(new_no_patterns[j], sub_size, sub, nopat);
no_pats.push_back(nopat);
no_pats.push_back(subst(new_no_patterns[j], sub_size, sub));
}
result = m.mk_quantifier(true,
result = m.mk_quantifier(forall_k,
names.size(),
sorts.c_ptr(),
names.c_ptr(),

View file

@ -1383,7 +1383,7 @@ br_status bv_rewriter::mk_bv2int(expr * arg, expr_ref & result) {
--i;
tmp = args[i].get();
tmp = m_autil.mk_mul(m_autil.mk_numeral(power(numeral(2), sz), true), tmp);
args[i] = tmp;
args[i] = std::move(tmp);
sz += get_bv_size(to_app(arg)->get_arg(i));
}
result = m_autil.mk_add(args.size(), args.c_ptr());
@ -2400,8 +2400,8 @@ bool bv_rewriter::isolate_term(expr* lhs, expr* rhs, expr_ref& result) {
return false;
}
unsigned sz = to_app(rhs)->get_num_args();
expr_ref t1(m()), t2(m());
t1 = to_app(rhs)->get_arg(0);
expr * t1 = to_app(rhs)->get_arg(0);
expr_ref t2(m());
if (sz > 2) {
t2 = m().mk_app(get_fid(), OP_BADD, sz-1, to_app(rhs)->get_args()+1);
}
@ -2597,14 +2597,10 @@ br_status bv_rewriter::mk_eq_core(expr * lhs, expr * rhs, expr_ref & result) {
result = m().mk_bool_val(new_lhs == new_rhs);
return BR_DONE;
}
}
else {
new_lhs = lhs;
new_rhs = rhs;
lhs = new_lhs;
rhs = new_rhs;
}
lhs = new_lhs;
rhs = new_rhs;
// Try to rewrite t1 + t2 = c --> t1 = c - t2
// Reason: it is much cheaper to bit-blast.
if (isolate_term(lhs, rhs, result)) {

View file

@ -125,7 +125,7 @@ struct bv_trailing::imp {
for (unsigned i = 0; i < num; ++i) {
expr * const curr = a->get_arg(i);
VERIFY(to_rm == remove_trailing(curr, to_rm, tmp, depth - 1));
new_args.push_back(tmp);
new_args.push_back(std::move(tmp));
}
result = m.mk_app(m_util.get_fid(), OP_BADD, new_args.size(), new_args.c_ptr());
return to_rm;
@ -150,7 +150,7 @@ struct bv_trailing::imp {
numeral c_val;
unsigned c_sz;
if (!m_util.is_numeral(tmp, c_val, c_sz) || !c_val.is_one())
new_args.push_back(tmp);
new_args.push_back(std::move(tmp));
const unsigned sz = m_util.get_bv_size(coefficient);
const unsigned new_sz = sz - retv;
@ -204,7 +204,7 @@ struct bv_trailing::imp {
expr_ref_vector new_args(m);
for (unsigned j = 0; j < i; ++j)
new_args.push_back(a->get_arg(j));
if (new_last) new_args.push_back(new_last);
if (new_last) new_args.push_back(std::move(new_last));
result = new_args.size() == 1 ? new_args.get(0)
: m_util.mk_concat(new_args.size(), new_args.c_ptr());
return retv;

View file

@ -133,7 +133,7 @@ void der::operator()(quantifier * q, expr_ref & r, proof_ref & pr) {
// Eliminate variables that have become unused
if (reduced && is_forall(r)) {
quantifier * q = to_quantifier(r);
elim_unused_vars(m_manager, q, params_ref(), r);
r = elim_unused_vars(m_manager, q, params_ref());
if (m_manager.proofs_enabled()) {
proof * p1 = m_manager.mk_elim_unused_vars(q, r);
pr = m_manager.mk_transitivity(pr, p1);
@ -343,8 +343,7 @@ void der::create_substitution(unsigned sz) {
expr_ref cur(m_map[m_order[i]], m_manager);
// do all the previous substitutions before inserting
expr_ref r(m_manager);
m_subst(cur, m_subst_map.size(), m_subst_map.c_ptr(), r);
expr_ref r = m_subst(cur, m_subst_map.size(), m_subst_map.c_ptr());
unsigned inx = sz - m_order[i]- 1;
SASSERT(m_subst_map[inx]==0);
@ -369,21 +368,18 @@ void der::apply_substitution(quantifier * q, expr_ref & r) {
unsigned sz = m_new_args.size();
expr_ref t(m_manager);
t = (sz == 1) ? m_new_args[0] : m_manager.mk_or(sz, m_new_args.c_ptr());
expr_ref new_e(m_manager);
m_subst(t, m_subst_map.size(), m_subst_map.c_ptr(), new_e);
expr_ref new_e = m_subst(t, m_subst_map.size(), m_subst_map.c_ptr());
// don't forget to update the quantifier patterns
expr_ref_buffer new_patterns(m_manager);
expr_ref_buffer new_no_patterns(m_manager);
for (unsigned j = 0; j < q->get_num_patterns(); j++) {
expr_ref new_pat(m_manager);
m_subst(q->get_pattern(j), m_subst_map.size(), m_subst_map.c_ptr(), new_pat);
expr_ref new_pat = m_subst(q->get_pattern(j), m_subst_map.size(), m_subst_map.c_ptr());
new_patterns.push_back(new_pat);
}
for (unsigned j = 0; j < q->get_num_no_patterns(); j++) {
expr_ref new_nopat(m_manager);
m_subst(q->get_no_pattern(j), m_subst_map.size(), m_subst_map.c_ptr(), new_nopat);
expr_ref new_nopat = m_subst(q->get_no_pattern(j), m_subst_map.size(), m_subst_map.c_ptr());
new_no_patterns.push_back(new_nopat);
}

Some files were not shown because too many files have changed in this diff Show more